diff options
| author | t <t@tjp.lol> | 2026-07-11 12:08:14 -0600 |
|---|---|---|
| committer | t <t@tjp.lol> | 2026-07-11 12:10:15 -0600 |
| commit | 2ab0e23eca3c5cac82d948e506b3f1cb81bedd18 (patch) | |
| tree | 46dc28dcea6265ece0f4763cdff372f84578e172 | |
| parent | 9faffbf6bc5083239d69a2daedac273e6d814bc3 (diff) | |
Migrate site pages to Weft templates and Markdown
| -rw-r--r-- | .gitignore | 8 | ||||
| -rw-r--r-- | .stignore.shared | 1 | ||||
| -rw-r--r-- | _docs/PROSE_AUDIT.md | 22 | ||||
| -rw-r--r-- | about/index.html | 17 | ||||
| -rw-r--r-- | about/index.html.tmpl | 50 | ||||
| -rw-r--r-- | feed.xml | 2 | ||||
| -rw-r--r-- | feed.xml.tmpl | 20 | ||||
| -rw-r--r-- | index.html | 24 | ||||
| -rw-r--r-- | index.html.tmpl | 45 | ||||
| -rw-r--r-- | notes/_plain-html.html | 70 | ||||
| -rw-r--r-- | notes/_plain-html.md | 28 | ||||
| -rw-r--r-- | notes/index.html | 11 | ||||
| -rw-r--r-- | notes/index.html.tmpl | 31 | ||||
| -rw-r--r-- | projects/index.html | 12 | ||||
| -rw-r--r-- | projects/index.html.tmpl | 28 | ||||
| -rw-r--r-- | site.tmpl | 90 | ||||
| -rw-r--r-- | weblog/_moving-off-gemini.html | 88 | ||||
| -rw-r--r-- | weblog/_moving-off-gemini.md | 46 | ||||
| -rw-r--r-- | weblog/index.html | 13 | ||||
| -rw-r--r-- | weblog/index.html.tmpl | 27 |
20 files changed, 416 insertions, 217 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..19f2e83 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +# Weft outputs (generated in place at every depth). +*.html +/feed.xml +/.weft-generated.json +/.weft-txn-* + +# Device-local Syncthing configuration; .stignore.shared is synchronized. +/.stignore diff --git a/.stignore.shared b/.stignore.shared new file mode 100644 index 0000000..2d19fc7 --- /dev/null +++ b/.stignore.shared @@ -0,0 +1 @@ +*.html diff --git a/_docs/PROSE_AUDIT.md b/_docs/PROSE_AUDIT.md index eafde4b..8dd3b2b 100644 --- a/_docs/PROSE_AUDIT.md +++ b/_docs/PROSE_AUDIT.md @@ -5,15 +5,15 @@ approve the copy for publication or supply replacement prose. | Source | Prose locations | Disposition | | --- | --- | --- | -| `index.html` | document title and description; brand tagline; navigation labels; two introductory paragraphs; section headings; “all posts” label; elsewhere labels and destinations; footer text | Keep for manual review. Fictional post and tag listings were removed. “From the notes” is commented out. | -| `about/index.html` | document title and description; navigation labels; About heading; two biography/contact paragraphs; Elsewhere heading, labels, and destinations; Colophon heading; colophon paragraph and six list items; footer text | Keep for manual rewrite. The colophon contains obsolete hand-written/no-build claims and must gain the planned licence and AI-assistance wording. | -| `projects/index.html` | document title and description; navigation labels; introductory sentence; Maintained and Archived / for fun headings; footer text | Keep for manual review. Placeholder instructions, fictional project names/descriptions, tag labels, and archived-project labels were removed. | -| `weblog/index.html` | document title and description; navigation labels; introductory paragraph and subscription label; footer text | Keep for manual review. Fictional year headings, dates, post titles, and links were removed. | -| `weblog/_moving-off-gemini.html` | document title and description; navigation labels; post date and title; placeholder notice; all post headings, paragraphs, list items, quotation, code sample, and inline link labels; post navigation; footer text | Archived fictional reference only. Its tag labels were removed. Do not publish, list, render, or use as authored site copy. | -| `notes/index.html` | document title and description; navigation labels; introductory paragraph; Start here and All notes headings; footer text | Keep hidden for manual review until real vault publication works. Fictional note labels and links were removed. | -| `notes/_plain-html.html` | document title and description; navigation labels; tended/planted metadata and title; placeholder notice; all note headings, paragraphs, list items, wiki-link labels, backlinks heading and labels; footer text | Archived fictional reference only. Do not publish, list, render, or use as authored site copy. | -| `feed.xml` | feed title; subtitle; author name and email | Keep for manual review. All fictional entry titles, summaries, dates, IDs, and links were removed; the feed is intentionally empty. | +| `index.html.tmpl` | document title and description; brand tagline; navigation labels; two introductory paragraphs; section headings; “all posts” label; elsewhere labels and destinations; footer text | Migrated to a direct homepage template. Fictional post and tag listings were removed. “From the notes” is commented out. | +| `about/index.html.tmpl` | document title and description; navigation labels; About heading; two biography/contact paragraphs; Elsewhere heading, labels, and destinations; Colophon heading; colophon paragraph and seven list items; footer text | Migrated to a direct template because its custom colophon structure and inline classes are not representable in raw-HTML-disabled Markdown. Obsolete hand-written/no-build claims were replaced with the generator, licence, and AI-assistance disclosure required by the plan. | +| `projects/index.html.tmpl` | document title and description; navigation labels; introductory sentence; Maintained and Archived / for fun headings; footer text | Migrated to a direct index template. Placeholder instructions, fictional project names/descriptions, tag labels, and archived-project labels were removed. | +| `weblog/index.html.tmpl` | document title and description; navigation labels; introductory paragraph and subscription label; footer text | Migrated to a direct index template. Fictional year headings, dates, post titles, and links were removed. | +| `weblog/_moving-off-gemini.md` | document description; post date and title; placeholder notice; all post headings, paragraphs, list items, quotation, code sample, and inline link labels | Archived fictional Markdown reference only. Its tag labels were removed. The underscore prefix keeps it out of discovery, rendering, listings, and feeds. | +| `notes/index.html.tmpl` | document title and description; navigation labels; introductory paragraph; Start here and All notes headings; footer text | Migrated to a direct index template and kept hidden until real vault publication works. Fictional note labels and links were removed. | +| `notes/_plain-html.md` | document description; tended/planted metadata and title; placeholder notice; all note headings, paragraphs, list items, wiki-link labels, backlinks heading and labels | Archived fictional Markdown reference only. The underscore prefix keeps it out of discovery, rendering, and listings. | +| `feed.xml.tmpl` | feed title; subtitle; author name and email | Migrated to a direct Atom template. All fictional entries remain removed; the feed is valid and intentionally empty until real weblog Markdown exists. | -Repeated site-wide prose also needing one manual decision in the future shared -templates: brand text, navigation labels, feed label, footer text, licence -notice, and the currently commented Notes and webring labels. +Repeated site-wide prose lives in `site.tmpl`: brand text, navigation labels, +the “feed” label, the direct CC BY 4.0 footer notice, and the currently +commented Notes and webring labels. diff --git a/about/index.html b/about/index.html index 71a8cd0..99f9a22 100644 --- a/about/index.html +++ b/about/index.html @@ -14,9 +14,9 @@ <h1 class="brand"><a href="../index.html">~tjp<span class="cur"> $_</span></a></h1> <nav class="main"> <a href="../weblog/index.html">weblog</a> - <!-- <a href="../notes/index.html">notes</a> --> + <a href="../projects/index.html">projects</a> - <a href="../about/index.html" aria-current="page">about</a> + <a href="index.html" aria-current="page">about</a> <a href="../feed.xml">feed</a> </nav> </header> @@ -42,12 +42,13 @@ <div class="backlinks"> <h2>Colophon</h2> <div class="note-body"> - <p>This site is hand-written HTML and a single <a href="../style.css">stylesheet</a>. There is no JavaScript anywhere — not deferred, not optional, none. It renders identically with scripts disabled because there is nothing to disable.</p> + <p>This site is generated from Markdown and Go templates by Weft, with a single <a href="../style.css">stylesheet</a>. There is no JavaScript anywhere — not deferred, not optional, none. It renders identically with scripts disabled because there is nothing to disable.</p> <ul> <li><strong>Type:</strong> your system's UI font for prose, your system's monospace for headings and code. No web fonts, no network requests for type.</li> <li><strong>Colour:</strong> light and dark themes via <code>prefers-color-scheme</code> — it follows your OS setting, in pure CSS.</li> - <li><strong>Weblog:</strong> written as gemtext in my <a href="../projects/index.html">capsule</a>, converted to HTML with a small script.</li> + <li><strong>Weblog:</strong> published from Markdown as static HTML.</li> <li><strong>Notes:</strong> authored in Obsidian, synced across my devices with Syncthing, published as static pages.</li> + <li><strong>Build:</strong> Weft recursively renders Markdown and Go templates. AI may assist with coding and batch refactoring, but not with published post prose.</li> <li><strong>Hosting:</strong> static files. Nothing to run, nothing to patch.</li> <li><strong>Licence:</strong> content is <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a> unless a page says otherwise. Take it, remix it, just credit me.</li> </ul> @@ -57,13 +58,11 @@ </main> <footer> - <!-- <div class="ring"> - <span>webring:</span> - <a href="#">← prev</a><a href="#">rand</a><a href="#">next →</a> - </div> --> - <p>hand-written in slc · ©2026 tjp · <a href="../feed.xml">feed</a></p> + + <p>©2026 tjp · content <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a> unless noted · <a href="../feed.xml">feed</a></p> </footer> </div> </body> </html> + diff --git a/about/index.html.tmpl b/about/index.html.tmpl new file mode 100644 index 0000000..065fdc3 --- /dev/null +++ b/about/index.html.tmpl @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<title>About & colophon — tjp.lol</title> +<meta name="description" content="About tjp and how this site is built."> +<link rel="stylesheet" href="../style.css"> +</head> +<body> +<div class="wrap"> + +{{template "header" .}} + <main> + <article class="post"> + <div class="post-head"> + <h1>About</h1> + </div> + <div class="note-body"> + <p>I'm tjp — an elder-millennial software engineer living in Salt Lake City, Utah. I write mostly Python, spend too long in the terminal, and care about software that's small, legible, and built to last.</p> + <p>This site is where I keep my <a href="../weblog/index.html">writing</a>. If you want to reach me, <a href="mailto:t@tjp.lol">t@tjp.lol</a> is the best way.</p> + + <h2>Elsewhere</h2> + <ul> + <li><span class="mono">email</span> — <a href="mailto:t@tjp.lol">t@tjp.lol</a></li> + <li><span class="mono">code</span> — <a href="https://github.com/teepark">github.com/teepark</a></li> + <li><span class="mono">fedi</span> — <a href="https://tilde.zone/@tjpcc" rel="me">@tjpcc@tilde.zone</a></li> + <li><span class="mono">gemini</span> — <code>gemini://gemini.ctrl-c.club/~tjp/</code></li> + </ul> + </div> + + <div class="backlinks"> + <h2>Colophon</h2> + <div class="note-body"> + <p>This site is generated from Markdown and Go templates by Weft, with a single <a href="../style.css">stylesheet</a>. There is no JavaScript anywhere — not deferred, not optional, none. It renders identically with scripts disabled because there is nothing to disable.</p> + <ul> + <li><strong>Type:</strong> your system's UI font for prose, your system's monospace for headings and code. No web fonts, no network requests for type.</li> + <li><strong>Colour:</strong> light and dark themes via <code>prefers-color-scheme</code> — it follows your OS setting, in pure CSS.</li> + <li><strong>Weblog:</strong> published from Markdown as static HTML.</li> + <li><strong>Notes:</strong> authored in Obsidian, synced across my devices with Syncthing, published as static pages.</li> + <li><strong>Build:</strong> Weft recursively renders Markdown and Go templates. AI may assist with coding and batch refactoring, but not with published post prose.</li> + <li><strong>Hosting:</strong> static files. Nothing to run, nothing to patch.</li> + <li><strong>Licence:</strong> content is <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a> unless a page says otherwise. Take it, remix it, just credit me.</li> + </ul> + </div> + </div> + </article> + </main> + +{{template "footer" .}} @@ -1,4 +1,3 @@ -<?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom"> <title>tjp.lol</title> <subtitle>Notes, code, and longer thoughts from an elder-millennial software engineer in Salt Lake City.</subtitle> @@ -10,4 +9,5 @@ <name>tjp</name> <email>t@tjp.lol</email> </author> + </feed> diff --git a/feed.xml.tmpl b/feed.xml.tmpl new file mode 100644 index 0000000..961ee41 --- /dev/null +++ b/feed.xml.tmpl @@ -0,0 +1,20 @@ +<feed xmlns="http://www.w3.org/2005/Atom"> + <title>tjp.lol</title> + <subtitle>Notes, code, and longer thoughts from an elder-millennial software engineer in Salt Lake City.</subtitle> + <link href="https://tjp.lol/feed.xml" rel="self"/> + <link href="https://tjp.lol/"/> + {{$posts := sortPages (index .Pages "weblog") "post_date"}}{{with slicePages $posts 0 1}}<updated>{{range .}}{{rfc3339 (index .Meta "post_date")}}{{end}}</updated>{{else}}<updated>2026-07-11T00:00:00Z</updated>{{end}} + <id>https://tjp.lol/</id> + <author> + <name>tjp</name> + <email>t@tjp.lol</email> + </author> + {{range $posts}}<entry> + <title>{{.Title}}</title> + <link href="{{.CanonicalURL}}"/> + <id>{{.CanonicalURL}}</id> + <published>{{rfc3339 (index .Meta "post_date")}}</published> + <updated>{{if index .Meta "updated"}}{{rfc3339 (index .Meta "updated")}}{{else}}{{rfc3339 (index .Meta "post_date")}}{{end}}</updated> + <content type="html">{{xml (joinSections .Sections)}}</content> + </entry>{{end}} +</feed> @@ -16,7 +16,7 @@ <p class="tag">Elder-millennial software engineer in Salt Lake City, Utah. Writing about code, tools, and the small web.</p> <nav class="main"> <a href="weblog/index.html">weblog</a> - <!-- <a href="notes/index.html">notes</a> --> + <a href="projects/index.html">projects</a> <a href="about/index.html">about</a> <a href="feed.xml">feed</a> @@ -26,7 +26,7 @@ <main> <section class="intro"> <p>Welcome in. This site is my writing desk: weblog posts moving over from my <span class="mono">gemini://</span> capsule, plus a public cut of the notes I keep in Obsidian and sync across my machines with Syncthing.</p> - <p>Plain HTML and CSS. No JavaScript, no build step, no tracking — it reads exactly the same with scripts turned off. That's the point.</p> + <p>Plain HTML and CSS. No JavaScript, no tracking — it reads exactly the same with scripts turned off. That's the point.</p> </section> <section> @@ -44,28 +44,16 @@ <li><span class="k">gemini</span><a href="about/index.html">gemini://…/~tjp</a></li> </ul> </section> - <!-- <section> - <h2 class="sec">from the notes</h2> - <ul class="links"> - <li><a href="notes/plain-html.html">The case for plain HTML</a></li> - <li><a href="notes/index.html">Home-lab & self-hosting</a></li> - <li><a href="notes/index.html">Emacs config, annotated</a></li> - <li><a href="notes/index.html">Books I keep re-reading</a></li> - </ul> - </section> --> + </div> </main> <footer> - <!-- <div class="ring"> - <span>webring:</span> - <a href="#">← prev</a> - <a href="#">rand</a> - <a href="#">next →</a> - </div> --> - <p>hand-written in slc · ©2026 tjp · content <a href="about/index.html">CC BY 4.0</a> unless noted · <a href="feed.xml">feed</a></p> + + <p>©2026 tjp · content <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a> unless noted · <a href="feed.xml">feed</a></p> </footer> </div> </body> </html> + diff --git a/index.html.tmpl b/index.html.tmpl new file mode 100644 index 0000000..83a9a4f --- /dev/null +++ b/index.html.tmpl @@ -0,0 +1,45 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<title>tjp.lol</title> +<meta name="description" content="Personal site of tjp — software engineer in Salt Lake City. Weblog, notes, projects."> +<link rel="stylesheet" href="style.css"> +<link rel="alternate" type="application/atom+xml" title="tjp.lol" href="feed.xml"> +</head> +<body> +<div class="wrap"> + +{{template "header" .}} + <main> + <section class="intro"> + <p>Welcome in. This site is my writing desk: weblog posts moving over from my <span class="mono">gemini://</span> capsule, plus a public cut of the notes I keep in Obsidian and sync across my machines with Syncthing.</p> + <p>Plain HTML and CSS. No JavaScript, no tracking — it reads exactly the same with scripts turned off. That's the point.</p> + </section> + + <section> + <h2 class="sec">recent posts</h2> + {{$posts := sortPages (index .Pages "weblog") "post_date"}}{{with $posts}}<ul class="posts"> + {{range slicePages . 0 5}}<li><time datetime="{{date (index .Meta "post_date") "2006-01-02"}}">{{date (index .Meta "post_date") "2006-01-02"}}</time><a href="{{rel "index.html" .OutputPath}}">{{.Title}}</a></li>{{end}} + </ul> + {{end}}<p style="margin-top:.9rem;font-size:.9rem;"><a href="weblog/index.html">all posts →</a></p> + </section> + + <div class="cols"> + <section> + <h2 class="sec">elsewhere</h2> + <ul class="links"> + <li><span class="k">email</span><a href="mailto:t@tjp.lol">t@tjp.lol</a></li> + <li><span class="k">code</span><a href="https://github.com/teepark">github.com/teepark</a></li> + <li><span class="k">fedi</span><a href="https://tilde.zone/@tjpcc" rel="me">@tjpcc@tilde.zone</a></li> + <li><span class="k">gemini</span><a href="about/index.html">gemini://…/~tjp</a></li> + </ul> + </section> + <!-- <section> + <h2 class="sec">from the notes</h2> + </section> --> + </div> + </main> + +{{template "footer" .}} diff --git a/notes/_plain-html.html b/notes/_plain-html.html deleted file mode 100644 index d60275e..0000000 --- a/notes/_plain-html.html +++ /dev/null @@ -1,70 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<title>The case for plain HTML — notes — tjp.lol</title> -<meta name="description" content="A note on writing plain, durable HTML."> -<link rel="stylesheet" href="../style.css"> -</head> -<body> -<div class="wrap"> - - <header class="site"> - <h1 class="brand"><a href="../index.html">~tjp<span class="cur"> $_</span></a></h1> - <nav class="main"> - <a href="../weblog/index.html">weblog</a> - <a href="../notes/index.html" aria-current="page">notes</a> - <a href="../projects/index.html">projects</a> - <a href="../about/index.html">about</a> - <a href="../feed.xml">rss</a> - </nav> - </header> - - <main> - <article class="post"> - <div class="post-head"> - <p class="meta"><a href="../notes/index.html" style="text-decoration:none;">← notes</a> / tended <time datetime="2026-05-30">2026-05-30</time> · planted <time datetime="2024-08-11">2024-08-11</time></p> - <h1>The case for plain HTML</h1> - </div> - - <div class="note-body"> - <p><em>A note, not an essay — expect it to change. This page shows how a wiki note reads: internal <a class="wiki" href="index.html">[[wiki links]]</a> render as underlined-dotted links, and a backlinks panel sits at the bottom.</em></p> - - <p>A hand-written HTML page is the most durable document format I know of that still looks like a document. It has no runtime, no dependencies, and no version that can go out of date. A file I wrote in 2004 opens today, pixel-for-pixel, in a browser that didn't exist then.</p> - - <p>This connects to <a class="wiki" href="index.html">Gemtext & the small web</a> — both are bets that <em>constraint outlives capability</em>. See also <a class="wiki" href="index.html">How I take notes</a> for why I keep the source in plain text.</p> - - <h2>Things I no longer do</h2> - <ul> - <li>Reach for a framework before there's a second page.</li> - <li>Add a build step to save five keystrokes.</li> - <li>Load a web font when the reader already owns a good one.</li> - </ul> - - <h2>The test</h2> - <p>Turn JavaScript off. If the page is worse, I've added fragility I have to maintain forever. If it's identical, I'm done. This whole site passes that test — see the <a class="wiki" href="../about/index.html">colophon</a>.</p> - </div> - - <div class="backlinks"> - <h2>Linked from</h2> - <ul class="posts"> - <li><a href="index.html">Gemtext & the small web</a></li> - <li><a href="index.html">Home-lab & self-hosting</a></li> - <li><a href="../weblog/moving-off-gemini.html">Moving my weblog off Gemini (without leaving it)</a></li> - </ul> - </div> - </article> - </main> - - <footer> - <div class="ring"> - <span>webring:</span> - <a href="#">← prev</a><a href="#">rand</a><a href="#">next →</a> - </div> - <p>hand-written in slc · ©2026 tjp · <a href="../feed.xml">feed</a></p> - </footer> - -</div> -</body> -</html> diff --git a/notes/_plain-html.md b/notes/_plain-html.md new file mode 100644 index 0000000..6d6e078 --- /dev/null +++ b/notes/_plain-html.md @@ -0,0 +1,28 @@ +--- +description: A note on writing plain, durable HTML. +planted: 2024-08-11 +tended: 2026-05-30 +--- +# The case for plain HTML + +*A note, not an essay — expect it to change. This page shows how a wiki note reads: internal wiki links render as underlined-dotted links, and a backlinks panel sits at the bottom.* + +A hand-written HTML page is the most durable document format I know of that still looks like a document. It has no runtime, no dependencies, and no version that can go out of date. A file I wrote in 2004 opens today, pixel-for-pixel, in a browser that didn't exist then. + +This connects to [Gemtext & the small web](index.html) — both are bets that *constraint outlives capability*. See also [How I take notes](index.html) for why I keep the source in plain text. + +## Things I no longer do + +- Reach for a framework before there's a second page. +- Add a build step to save five keystrokes. +- Load a web font when the reader already owns a good one. + +## The test + +Turn JavaScript off. If the page is worse, I've added fragility I have to maintain forever. If it's identical, I'm done. This whole site passes that test — see the [colophon](../about/index.html). + +## Linked from + +- [Gemtext & the small web](index.html) +- [Home-lab & self-hosting](index.html) +- [Moving my weblog off Gemini (without leaving it)](../weblog/moving-off-gemini.html) diff --git a/notes/index.html b/notes/index.html index 1a8db13..ea988cf 100644 --- a/notes/index.html +++ b/notes/index.html @@ -14,7 +14,7 @@ <h1 class="brand"><a href="../index.html">~tjp<span class="cur"> $_</span></a></h1> <nav class="main"> <a href="../weblog/index.html">weblog</a> - <!-- <a href="../notes/index.html" aria-current="page">notes</a> --> + <a href="../projects/index.html">projects</a> <a href="../about/index.html">about</a> <a href="../feed.xml">feed</a> @@ -32,17 +32,16 @@ <section> <h2 class="sec">all notes</h2> + </section> </main> <footer> - <!-- <div class="ring"> - <span>webring:</span> - <a href="#">← prev</a><a href="#">rand</a><a href="#">next →</a> - </div> --> - <p>hand-written in slc · ©2026 tjp · <a href="../feed.xml">feed</a></p> + + <p>©2026 tjp · content <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a> unless noted · <a href="../feed.xml">feed</a></p> </footer> </div> </body> </html> + diff --git a/notes/index.html.tmpl b/notes/index.html.tmpl new file mode 100644 index 0000000..468a466 --- /dev/null +++ b/notes/index.html.tmpl @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<title>Notes — tjp.lol</title> +<meta name="description" content="A public cut of my Obsidian notes — a small digital garden."> +<link rel="stylesheet" href="../style.css"> +</head> +<body> +<div class="wrap"> + +{{template "header" .}} + <main> + <section class="intro"> + <p>This is a digital garden — a public slice of the notes I keep in Obsidian. Unlike the <a href="../weblog/index.html">weblog</a>, these aren't essays. They're living pages: some are a paragraph, some are years old, most link to each other. Start anywhere and follow the threads.</p> + </section> + + <section> + <h2 class="sec">start here</h2> + </section> + + <section> + <h2 class="sec">all notes</h2> + {{$notes := sortPages (index .Pages "notes") "mod_time"}}{{with $notes}}<div class="note-index"> + {{range .}}<a href="{{rel "notes/index.html" .OutputPath}}">{{.Title}}</a>{{end}} + </div>{{end}} + </section> + </main> + +{{template "footer" .}} diff --git a/projects/index.html b/projects/index.html index 0943b48..6bc0dc5 100644 --- a/projects/index.html +++ b/projects/index.html @@ -14,8 +14,8 @@ <h1 class="brand"><a href="../index.html">~tjp<span class="cur"> $_</span></a></h1> <nav class="main"> <a href="../weblog/index.html">weblog</a> - <!-- <a href="../notes/index.html">notes</a> --> - <a href="../projects/index.html" aria-current="page">projects</a> + + <a href="index.html" aria-current="page">projects</a> <a href="../about/index.html">about</a> <a href="../feed.xml">feed</a> </nav> @@ -36,13 +36,11 @@ </main> <footer> - <!-- <div class="ring"> - <span>webring:</span> - <a href="#">← prev</a><a href="#">rand</a><a href="#">next →</a> - </div> --> - <p>hand-written in slc · ©2026 tjp · <a href="../feed.xml">feed</a></p> + + <p>©2026 tjp · content <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a> unless noted · <a href="../feed.xml">feed</a></p> </footer> </div> </body> </html> + diff --git a/projects/index.html.tmpl b/projects/index.html.tmpl new file mode 100644 index 0000000..a99a10b --- /dev/null +++ b/projects/index.html.tmpl @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<title>Projects — tjp.lol</title> +<meta name="description" content="Things tjp has built."> +<link rel="stylesheet" href="../style.css"> +</head> +<body> +<div class="wrap"> + +{{template "header" .}} + <main> + <section class="intro"> + <p>Small things I've built and still maintain. Most live on <a href="https://github.com/teepark">GitHub</a>.</p> + </section> + + <section> + <h2 class="sec">maintained</h2> + </section> + + <section> + <h2 class="sec">archived / for fun</h2> + </section> + </main> + +{{template "footer" .}} diff --git a/site.tmpl b/site.tmpl new file mode 100644 index 0000000..6c60443 --- /dev/null +++ b/site.tmpl @@ -0,0 +1,90 @@ +{{define "head"}}<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<title>{{if eq .OutputPath "about/index.html"}}About & colophon{{else}}{{.Title}}{{end}} — tjp.lol</title> +{{with index .Meta "description"}}<meta name="description" content="{{.}}"> +{{end}}<link rel="stylesheet" href="{{rel .OutputPath "style.css"}}"> +{{if or (eq .OutputPath "weblog/index.html") (index .Meta "post_date")}}<link rel="alternate" type="application/atom+xml" title="tjp.lol" href="{{rel .OutputPath "feed.xml"}}"> +{{end}}</head> +<body> +<div class="wrap"> +{{end}} + +{{define "header"}} <header class="site"> + <h1 class="brand"><a href="{{rel .OutputPath "index.html"}}">~tjp<span class="cur"> $_</span></a></h1> + {{if eq .OutputPath "index.html"}}<p class="tag">Elder-millennial software engineer in Salt Lake City, Utah. Writing about code, tools, and the small web.</p> + {{end}}<nav class="main"> + <a href="{{rel .OutputPath "weblog/index.html"}}"{{if eq .OutputPath "weblog/index.html"}} aria-current="page"{{end}}>weblog</a> + <!-- <a href="{{rel .OutputPath "notes/index.html"}}"{{if eq .OutputPath "notes/index.html"}} aria-current="page"{{end}}>notes</a> --> + <a href="{{rel .OutputPath "projects/index.html"}}"{{if eq .OutputPath "projects/index.html"}} aria-current="page"{{end}}>projects</a> + <a href="{{rel .OutputPath "about/index.html"}}"{{if eq .OutputPath "about/index.html"}} aria-current="page"{{end}}>about</a> + <a href="{{rel .OutputPath "feed.xml"}}">feed</a> + </nav> + </header> +{{end}} + +{{define "footer"}} <footer> + <!-- <div class="ring"> + <span>webring:</span> + <a href="#">← prev</a><a href="#">rand</a><a href="#">next →</a> + </div> --> + <p>©2026 tjp · content <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a> unless noted · <a href="{{rel .OutputPath "feed.xml"}}">feed</a></p> + </footer> + +</div> +</body> +</html> +{{end}} + +{{define "page"}}{{template "head" .}}{{template "header" .}} + <main> + <article class="post"> + <div class="post-head"> + <h1>{{.Title}}</h1> + </div> + <div class="note-body"> + {{joinSections .Sections}} + </div> + </article> + </main> + +{{template "footer" .}}{{end}} + +{{define "weblog"}}{{template "head" .}}{{template "header" .}} + <main> + <article class="post"> + <div class="post-head"> + <p class="meta"><a href="{{rel .OutputPath "weblog/index.html"}}" style="text-decoration:none;">← weblog</a> / <time datetime="{{date (index .Meta "post_date") "2006-01-02"}}">{{date (index .Meta "post_date") "2006-01-02"}}</time></p> + <h1>{{.Title}}</h1> + </div> + + {{with index .Sections 0}}<div style="font-size:1.2em">{{.}}</div>{{end}} + {{joinSections (slice .Sections 1)}} + </article> + + <nav class="post-nav"> + <a href="{{rel .OutputPath "weblog/index.html"}}">← Older</a> + <a href="{{rel .OutputPath "weblog/index.html"}}">All posts</a> + <a href="{{rel .OutputPath "weblog/index.html"}}">Newer →</a> + </nav> + </main> + +{{template "footer" .}}{{end}} + +{{define "note"}}{{template "head" .}}{{template "header" .}} + <main> + <article class="post"> + <div class="post-head"> + <p class="meta"><a href="{{rel .OutputPath "notes/index.html"}}" style="text-decoration:none;">← notes</a></p> + <h1>{{.Title}}</h1> + </div> + + <div class="note-body"> + {{joinSections .Sections}} + </div> + </article> + </main> + +{{template "footer" .}}{{end}} diff --git a/weblog/_moving-off-gemini.html b/weblog/_moving-off-gemini.html deleted file mode 100644 index fdf6165..0000000 --- a/weblog/_moving-off-gemini.html +++ /dev/null @@ -1,88 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -<head> -<meta charset="utf-8"> -<meta name="viewport" content="width=device-width, initial-scale=1"> -<title>Moving my weblog off Gemini (without leaving it) — tjp.lol</title> -<meta name="description" content="How I mirror my Gemini capsule to the web without abandoning geminispace."> -<link rel="stylesheet" href="../style.css"> -<link rel="alternate" type="application/atom+xml" title="tjp.lol" href="../feed.xml"> -</head> -<body> -<div class="wrap"> - - <header class="site"> - <h1 class="brand"><a href="../index.html">~tjp<span class="cur"> $_</span></a></h1> - <nav class="main"> - <a href="../weblog/index.html" aria-current="page">weblog</a> - <a href="../notes/index.html">notes</a> - <a href="../projects/index.html">projects</a> - <a href="../about/index.html">about</a> - <a href="../feed.xml">rss</a> - </nav> - </header> - - <main> - <article class="post"> - <div class="post-head"> - <p class="meta"><a href="../weblog/index.html" style="text-decoration:none;">← weblog</a> / <time datetime="2026-06-30">2026-06-30</time></p> - <h1>Moving my weblog off Gemini (without leaving it)</h1> - </div> - - <p><em>This is placeholder text laid out so you can see how a full post reads. Replace it with the real <span class="mono">.gmi</span> content when you export the capsule — the structure below covers everything a converted Gemini post will need: headings, lists, quotes, code, and links.</em></p> - - <p>I've kept a capsule at <code>gemini://gemini.ctrl-c.club/~tjp/</code> for a few years now. Gemini is a lovely place to write: the format is so constrained that there's nothing to fiddle with, and the whole thing rewards plain, linear prose. But I wanted a web presence too — one that fits in with the personal sites I keep finding in webrings.</p> - - <h2>The plan</h2> - <p>The goal was never to abandon geminispace. It was to have both, from one source of truth. Gemtext is close enough to Markdown that a small converter gets you most of the way there:</p> - - <ul> - <li>Keep writing <code>.gmi</code> files in my capsule.</li> - <li>Run a converter that emits HTML with the same structure.</li> - <li>Wrap each page in the site template you're reading now.</li> - </ul> - - <h2>The converter</h2> - <p>Gemtext has exactly one block-level construct per line, which makes parsing almost insultingly simple. Here's the core of it:</p> - - <pre><code>while IFS= read -r line; do - case "$line" in - "### "*) echo "<h3>${line#### }</h3>" ;; - "## "*) echo "<h2>${line### }</h2>" ;; - "# "*) echo "<h1>${line## }</h1>" ;; - "=> "*) emit_link "$line" ;; - "* "*) emit_list_item "$line" ;; - "> "*) echo "<blockquote>${line#> }</blockquote>" ;; - "") echo "" ;; - *) echo "<p>$line</p>" ;; - esac -done < "$1"</code></pre> - - <p>That's genuinely most of it. The fiddly parts are link lines (<code>=></code> can be a bare URL or have link text) and collapsing runs of <code>* </code> lines into a single <code><ul></code>.</p> - - <blockquote>The best format is the one that outlives the tool you wrote it in. Gemtext will still be readable when this converter is long gone.</blockquote> - - <h2>What I kept</h2> - <p>No client-side anything. The web version renders identically with JavaScript disabled, because there is no JavaScript to disable. Fonts are whatever your system already has. The whole page is a few kilobytes.</p> - - <p>If you want the source, it lives with the rest of my <a href="../projects/index.html">projects</a>. And the capsule is still there — see the <a href="../about/index.html">colophon</a> for how it all fits together.</p> - </article> - - <nav class="post-nav"> - <a href="../weblog/index.html">← Older</a> - <a href="../weblog/index.html">All posts</a> - <a href="../weblog/index.html">Newer →</a> - </nav> - </main> - - <footer> - <div class="ring"> - <span>webring:</span> - <a href="#">← prev</a><a href="#">rand</a><a href="#">next →</a> - </div> - <p>hand-written in slc · ©2026 tjp · content <a href="../about/index.html">CC BY 4.0</a> · <a href="../feed.xml">feed</a></p> - </footer> - -</div> -</body> -</html> diff --git a/weblog/_moving-off-gemini.md b/weblog/_moving-off-gemini.md new file mode 100644 index 0000000..e0cafe0 --- /dev/null +++ b/weblog/_moving-off-gemini.md @@ -0,0 +1,46 @@ +--- +post_date: 2026-06-30 +description: How I mirror my Gemini capsule to the web without abandoning geminispace. +--- +# Moving my weblog off Gemini (without leaving it) + +*This is placeholder text laid out so you can see how a full post reads. Replace it with the real `.gmi` content when you export the capsule — the structure below covers everything a converted Gemini post will need: headings, lists, quotes, code, and links.* + +I've kept a capsule at `gemini://gemini.ctrl-c.club/~tjp/` for a few years now. Gemini is a lovely place to write: the format is so constrained that there's nothing to fiddle with, and the whole thing rewards plain, linear prose. But I wanted a web presence too — one that fits in with the personal sites I keep finding in webrings. + +## The plan + +The goal was never to abandon geminispace. It was to have both, from one source of truth. Gemtext is close enough to Markdown that a small converter gets you most of the way there: + +- Keep writing `.gmi` files in my capsule. +- Run a converter that emits HTML with the same structure. +- Wrap each page in the site template you're reading now. + +## The converter + +Gemtext has exactly one block-level construct per line, which makes parsing almost insultingly simple. Here's the core of it: + +```sh +while IFS= read -r line; do + case "$line" in + "### "*) echo "<h3>${line#### }</h3>" ;; + "## "*) echo "<h2>${line### }</h2>" ;; + "# "*) echo "<h1>${line## }</h1>" ;; + "=> "*) emit_link "$line" ;; + "* "*) emit_list_item "$line" ;; + "> "*) echo "<blockquote>${line#> }</blockquote>" ;; + "") echo "" ;; + *) echo "<p>$line</p>" ;; + esac +done < "$1" +``` + +That's genuinely most of it. The fiddly parts are link lines (`=>` can be a bare URL or have link text) and collapsing runs of `* ` lines into a single `<ul>`. + +> The best format is the one that outlives the tool you wrote it in. Gemtext will still be readable when this converter is long gone. + +## What I kept + +No client-side anything. The web version renders identically with JavaScript disabled, because there is no JavaScript to disable. Fonts are whatever your system already has. The whole page is a few kilobytes. + +If you want the source, it lives with the rest of my [projects](../projects/index.html). And the capsule is still there — see the [colophon](../about/index.html) for how it all fits together. diff --git a/weblog/index.html b/weblog/index.html index 8510f60..f67da6b 100644 --- a/weblog/index.html +++ b/weblog/index.html @@ -14,8 +14,8 @@ <header class="site"> <h1 class="brand"><a href="../index.html">~tjp<span class="cur"> $_</span></a></h1> <nav class="main"> - <a href="../weblog/index.html" aria-current="page">weblog</a> - <!-- <a href="../notes/index.html">notes</a> --> + <a href="index.html" aria-current="page">weblog</a> + <a href="../projects/index.html">projects</a> <a href="../about/index.html">about</a> <a href="../feed.xml">feed</a> @@ -27,16 +27,15 @@ <p>Longer-form writing. Most of these are migrating over from my Gemini capsule, so dates reflect the original posting. <a href="../feed.xml">Subscribe via RSS</a>.</p> </section> + </main> <footer> - <!-- <div class="ring"> - <span>webring:</span> - <a href="#">← prev</a><a href="#">rand</a><a href="#">next →</a> - </div> --> - <p>hand-written in slc · ©2026 tjp · <a href="../feed.xml">feed</a></p> + + <p>©2026 tjp · content <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a> unless noted · <a href="../feed.xml">feed</a></p> </footer> </div> </body> </html> + diff --git a/weblog/index.html.tmpl b/weblog/index.html.tmpl new file mode 100644 index 0000000..9d97024 --- /dev/null +++ b/weblog/index.html.tmpl @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<title>Weblog — tjp.lol</title> +<meta name="description" content="Weblog posts by tjp."> +<link rel="stylesheet" href="../style.css"> +<link rel="alternate" type="application/atom+xml" title="tjp.lol" href="../feed.xml"> +</head> +<body> +<div class="wrap"> + +{{template "header" .}} + <main> + <section class="intro"> + <p>Longer-form writing. Most of these are migrating over from my Gemini capsule, so dates reflect the original posting. <a href="../feed.xml">Subscribe via RSS</a>.</p> + </section> + + {{$posts := sortPages (index .Pages "weblog") "post_date"}}{{with $posts}}<section> + <ul class="posts"> + {{range .}}<li><time datetime="{{date (index .Meta "post_date") "2006-01-02"}}">{{date (index .Meta "post_date") "2006-01-02"}}</time><a href="{{rel "weblog/index.html" .OutputPath}}">{{.Title}}</a></li>{{end}} + </ul> + </section>{{end}} + </main> + +{{template "footer" .}} |
