first commit

This commit is contained in:
Blake Ridgway
2026-04-11 14:01:09 -05:00
commit 6915cab5f3
22 changed files with 1842 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
{{define "title"}}admin — paste.ridgwaysystems.org{{end}}
{{define "content"}}
{{$csrf := .CSRFToken}}
<div class="admin-wrap">
<div class="admin-header">
<h1>all pastes</h1>
<div class="admin-actions">
<a href="/new" class="btn">+ new paste</a>
</div>
</div>
{{if .Pastes}}
<table class="admin-table">
<thead>
<tr>
<th>id</th>
<th>title</th>
<th>language</th>
<th>created</th>
<th>expires</th>
<th>unlisted</th>
<th>actions</th>
</tr>
</thead>
<tbody>
{{range .Pastes}}
<tr {{if .Expired}}style="opacity:0.5"{{end}}>
<td><code><a href="/{{.ID}}">{{.ID}}</a></code></td>
<td>{{.Title}}</td>
<td><span class="lang-badge">{{.Language}}</span></td>
<td class="post-date">{{formatDate .CreatedAt}}</td>
<td class="post-date">{{expiryStr .}}</td>
<td>{{if .Unlisted}}<span class="tag">unlisted</span>{{end}}</td>
<td class="actions-cell">
<a href="/raw/{{.ID}}" class="btn btn-outline btn-sm">raw</a>
<form method="POST" action="/admin/delete/{{.ID}}" class="inline-form"
onsubmit="return confirm('Delete paste {{.ID}}?')">
<input type="hidden" name="csrf_token" value="{{$csrf}}">
<button type="submit" class="btn btn-danger btn-sm">delete</button>
</form>
</td>
</tr>
{{end}}
</tbody>
</table>
{{else}}
<p class="empty-state">No pastes yet. <a href="/new">Create one.</a></p>
{{end}}
</div>
{{end}}

View File

@@ -0,0 +1,18 @@
{{define "title"}}login — paste.ridgwaysystems.org{{end}}
{{define "content"}}
<div class="admin-login-wrap">
<h1>admin login</h1>
{{if .Error}}
<div class="form-error">{{.Error}}</div>
{{end}}
<form method="POST" action="/admin/login" class="login-form">
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
<label for="password">password</label>
<input type="password" id="password" name="password" autofocus autocomplete="current-password">
<button type="submit" class="btn">login</button>
</form>
</div>
{{end}}

46
templates/base.html Normal file
View File

@@ -0,0 +1,46 @@
{{define "base"}}<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{block "title" .Inner}}paste.ridgwaysystems.org{{end}}</title>
<meta name="description" content="{{block "meta-desc" .Inner}}A self-hosted code paste service.{{end}}">
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
<link rel="stylesheet" href="/static/css/style.css">
<link rel="stylesheet" href="/static/css/syntax.css">
</head>
<body>
<header class="site-header">
<nav class="nav">
<a href="/" class="nav-brand">paste.ridgwaysystems.org</a>
<ul class="nav-links">
<li><a href="/">pastes</a></li>
{{if .IsAdmin}}
<li><a href="/new">new paste</a></li>
<li><a href="/admin">admin</a></li>
<li>
<form method="POST" action="/admin/logout" class="inline-form">
<input type="hidden" name="csrf_token" value="">
<button type="submit" class="nav-logout-btn">logout</button>
</form>
</li>
{{end}}
<li><a href="https://ridgwaysystems.org">ridgwaysystems.org &rarr;</a></li>
</ul>
</nav>
</header>
<main class="main-content">
{{block "content" .Inner}}{{end}}
</main>
<footer class="site-footer">
<p>
<a href="/">paste.ridgwaysystems.org</a> &mdash;
<a href="https://ridgwaysystems.org">ridgwaysystems.org</a> &mdash;
self-hosted on FreeBSD
</p>
</footer>
</body>
</html>
{{end}}

33
templates/list.html Normal file
View File

@@ -0,0 +1,33 @@
{{define "title"}}pastes — paste.ridgwaysystems.org{{end}}
{{define "content"}}
<div class="page-header">
<h1>pastes</h1>
<p class="page-desc">Public code snippets.</p>
</div>
{{if .Pastes}}
<table class="admin-table">
<thead>
<tr>
<th>title</th>
<th>language</th>
<th>created</th>
<th>expires</th>
</tr>
</thead>
<tbody>
{{range .Pastes}}
<tr>
<td><a href="/{{.ID}}">{{.Title}}</a></td>
<td><span class="lang-badge">{{.Language}}</span></td>
<td class="post-date">{{formatDate .CreatedAt}}</td>
<td class="post-date">{{expiryStr .}}</td>
</tr>
{{end}}
</tbody>
</table>
{{else}}
<p class="empty-state">No public pastes yet.</p>
{{end}}
{{end}}

58
templates/new.html Normal file
View File

@@ -0,0 +1,58 @@
{{define "title"}}new paste — paste.ridgwaysystems.org{{end}}
{{define "content"}}
<div class="page-header">
<h1>new paste</h1>
</div>
{{if .Error}}
<div class="form-error">{{.Error}}</div>
{{end}}
<form method="POST" action="/new" class="paste-form">
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
<div class="form-row">
<label for="title">title</label>
<input type="text" id="title" name="title" placeholder="Untitled" autocomplete="off">
</div>
<div class="paste-form-meta">
<div class="form-row">
<label for="language">language</label>
<select id="language" name="language">
{{range .Languages}}
<option value="{{.}}">{{.}}</option>
{{end}}
</select>
</div>
<div class="form-row">
<label for="expiry">expires</label>
<select id="expiry" name="expiry">
<option value="never">never</option>
<option value="1h">1 hour</option>
<option value="1d">1 day</option>
<option value="7d">7 days</option>
<option value="30d">30 days</option>
</select>
</div>
<div class="form-row">
<label class="form-check">
<input type="checkbox" name="unlisted">
unlisted (not shown in public index)
</label>
</div>
</div>
<div class="form-row">
<label for="body">paste</label>
<textarea id="body" name="body" class="paste-textarea" placeholder="Paste your code here..." spellcheck="false" autocomplete="off" autocorrect="off" autocapitalize="off" required></textarea>
</div>
<div class="editor-footer">
<button type="submit" class="btn">create paste</button>
</div>
</form>
{{end}}

29
templates/paste.html Normal file
View File

@@ -0,0 +1,29 @@
{{define "title"}}{{.Paste.Title}} — paste.ridgwaysystems.org{{end}}
{{define "content"}}
<div class="paste-header">
<div>
<h1 style="margin:0 0 0.4em;">{{.Paste.Title}}</h1>
<div class="paste-meta">
<span><span class="lang-badge">{{.Paste.Language}}</span></span>
<span>created {{formatDateTime .Paste.CreatedAt}}</span>
<span>expires {{expiryStr .Paste}}</span>
{{if .Paste.Unlisted}}<span class="tag">unlisted</span>{{end}}
</div>
</div>
<div class="paste-actions">
<a href="/raw/{{.Paste.ID}}" class="btn btn-outline btn-sm">raw</a>
{{if .IsAdmin}}
<form method="POST" action="/admin/delete/{{.Paste.ID}}" class="inline-form"
onsubmit="return confirm('Delete this paste?')">
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
<button type="submit" class="btn btn-danger btn-sm">delete</button>
</form>
{{end}}
</div>
</div>
<div class="paste-code">
{{.Highlighted}}
</div>
{{end}}