From 2ab0e23eca3c5cac82d948e506b3f1cb81bedd18 Mon Sep 17 00:00:00 2001 From: t Date: Sat, 11 Jul 2026 12:08:14 -0600 Subject: Migrate site pages to Weft templates and Markdown --- .gitignore | 8 ++++ .stignore.shared | 1 + _docs/PROSE_AUDIT.md | 22 +++++------ about/index.html | 17 ++++---- about/index.html.tmpl | 50 +++++++++++++++++++++++ feed.xml | 2 +- feed.xml.tmpl | 20 ++++++++++ index.html | 24 +++-------- index.html.tmpl | 45 +++++++++++++++++++++ notes/_plain-html.html | 70 -------------------------------- notes/_plain-html.md | 28 +++++++++++++ notes/index.html | 11 +++--- notes/index.html.tmpl | 31 +++++++++++++++ projects/index.html | 12 +++--- projects/index.html.tmpl | 28 +++++++++++++ site.tmpl | 90 ++++++++++++++++++++++++++++++++++++++++++ weblog/_moving-off-gemini.html | 88 ----------------------------------------- weblog/_moving-off-gemini.md | 46 +++++++++++++++++++++ weblog/index.html | 13 +++--- weblog/index.html.tmpl | 27 +++++++++++++ 20 files changed, 416 insertions(+), 217 deletions(-) create mode 100644 .gitignore create mode 100644 .stignore.shared create mode 100644 about/index.html.tmpl create mode 100644 feed.xml.tmpl create mode 100644 index.html.tmpl delete mode 100644 notes/_plain-html.html create mode 100644 notes/_plain-html.md create mode 100644 notes/index.html.tmpl create mode 100644 projects/index.html.tmpl create mode 100644 site.tmpl delete mode 100644 weblog/_moving-off-gemini.html create mode 100644 weblog/_moving-off-gemini.md create mode 100644 weblog/index.html.tmpl 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 @@

~tjp $_

@@ -42,12 +42,13 @@ + 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 @@ + + + + + +tjp.lol + + + + + +
+ +{{template "header" .}} +
+
+

Welcome in. This site is my writing desk: weblog posts moving over from my gemini:// capsule, plus a public cut of the notes I keep in Obsidian and sync across my machines with Syncthing.

+

Plain HTML and CSS. No JavaScript, no tracking — it reads exactly the same with scripts turned off. That's the point.

+
+ +
+

recent posts

+ {{$posts := sortPages (index .Pages "weblog") "post_date"}}{{with $posts}}
    + {{range slicePages . 0 5}}
  • {{.Title}}
  • {{end}} +
+ {{end}}

all posts →

+
+ +
+
+

elsewhere

+ +
+ +
+
+ +{{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 @@ - - - - - -The case for plain HTML — notes — tjp.lol - - - - -
- -
-

~tjp $_

- -
- -
-
-
-

← notes  /  tended · planted

-

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 — both are bets that constraint outlives capability. See also How I take notes 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.

-
- - -
-
- - - -
- - 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 @@

~tjp $_

+ 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 @@ + + + + + +Notes — tjp.lol + + + + +
+ +{{template "header" .}} +
+
+

This is a digital garden — a public slice of the notes I keep in Obsidian. Unlike the weblog, 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.

+
+ +
+

start here

+
+ +
+

all notes

+ {{$notes := sortPages (index .Pages "notes") "mod_time"}}{{with $notes}}
+ {{range .}}{{.Title}}{{end}} +
{{end}} +
+
+ +{{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 @@

~tjp $_

@@ -36,13 +36,11 @@
- -

hand-written in slc · ©2026 tjp · feed

+ +

©2026 tjp · content CC BY 4.0 unless noted · feed

+ 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 @@ + + + + + +Projects — tjp.lol + + + + +
+ +{{template "header" .}} +
+
+

Small things I've built and still maintain. Most live on GitHub.

+
+ +
+

maintained

+
+ +
+

archived / for fun

+
+
+ +{{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"}} + + + + +{{if eq .OutputPath "about/index.html"}}About & colophon{{else}}{{.Title}}{{end}} — tjp.lol +{{with index .Meta "description"}} +{{end}} +{{if or (eq .OutputPath "weblog/index.html") (index .Meta "post_date")}} +{{end}} + +
+{{end}} + +{{define "header"}}
+

~tjp $_

+ {{if eq .OutputPath "index.html"}}

Elder-millennial software engineer in Salt Lake City, Utah. Writing about code, tools, and the small web.

+ {{end}} +
+{{end}} + +{{define "footer"}} + +
+ + +{{end}} + +{{define "page"}}{{template "head" .}}{{template "header" .}} +
+
+
+

{{.Title}}

+
+
+ {{joinSections .Sections}} +
+
+
+ +{{template "footer" .}}{{end}} + +{{define "weblog"}}{{template "head" .}}{{template "header" .}} +
+
+
+

← weblog  / 

+

{{.Title}}

+
+ + {{with index .Sections 0}}
{{.}}
{{end}} + {{joinSections (slice .Sections 1)}} +
+ + +
+ +{{template "footer" .}}{{end}} + +{{define "note"}}{{template "head" .}}{{template "header" .}} +
+
+
+

← notes

+

{{.Title}}

+
+ +
+ {{joinSections .Sections}} +
+
+
+ +{{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 @@ - - - - - -Moving my weblog off Gemini (without leaving it) — tjp.lol - - - - - -
- -
-

~tjp $_

- -
- -
-
-
-

← weblog  / 

-

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:

- -
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. And the capsule is still there — see the colophon for how it all fits together.

-
- - -
- - - -
- - 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 "

${line#### }

" ;; + "## "*) echo "

${line### }

" ;; + "# "*) echo "

${line## }

" ;; + "=> "*) emit_link "$line" ;; + "* "*) emit_list_item "$line" ;; + "> "*) echo "
${line#> }
" ;; + "") echo "" ;; + *) echo "

$line

" ;; + 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 `
+ 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 @@ + + + + + +Weblog — tjp.lol + + + + + +
+ +{{template "header" .}} +
+
+

Longer-form writing. Most of these are migrating over from my Gemini capsule, so dates reflect the original posting. Subscribe via RSS.

+
+ + {{$posts := sortPages (index .Pages "weblog") "post_date"}}{{with $posts}}
+
    + {{range .}}
  • {{.Title}}
  • {{end}} +
+
{{end}} +
+ +{{template "footer" .}} -- cgit v1.3