diff options
| author | Christian Cleberg <[email protected]> | 2026-08-11 02:20:00 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-08-11 20:35:15 -0500 |
| commit | f1b8d6d4a89c5d33615556af65aadeb71e7800cb (patch) | |
| tree | 7c1a049ed0eee6ff609a3251bdb7b9bbaf7de985 /content | |
| parent | 8ec9cdfeae71068a8924dd9f61b9cc28c947ec31 (diff) | |
| download | cleberg.net-f1b8d6d4a89c5d33615556af65aadeb71e7800cb.tar.gz cleberg.net-f1b8d6d4a89c5d33615556af65aadeb71e7800cb.tar.bz2 cleberg.net-f1b8d6d4a89c5d33615556af65aadeb71e7800cb.zip | |
Add an org-ssg build alongside the weblorg one
Builds the same site with org-ssg instead of weblorg, reproducing all 182 URLs the
current .build output has, plus 13 per-tag pages it does not.
org-ssg serve content -o /tmp/preview # write, with live reload
org-ssg build content -o _site --strict # build, failing on broken links
content/ is the source because it is the URL root: content/blog/post.org publishes at
/blog/post.html. Pointing at the repository root instead would prefix every URL with
/content/ and copy build.py, publish.el and LICENSE into the site as assets.
Added:
- content/org-ssg.toml — site metadata, an explicit nav, and four generated pages:
the home page, the blog index, the garden index, and tag pages with an index. URLs
come from #+SLUG:, which is why 2018-11-28-aes-encryption.org still publishes at
/blog/aes-encryption.html.
- content/templates/ — base, home, list and tags. Plain layouts using the .post-list
classes styles.css already defines, not a port of theme/templates/, which are
templatel and a different language.
- content/styles.css — a verbatim copy of theme/static/styles.css, because org-ssg
publishes assets from inside its source directory. `diff` between the two should stay
empty; consolidate them if this migration goes further.
Removed content/index.org. It held only #+title and #+description, both now [site]
settings, and a generated home page cannot share a URL with an authored one — org-ssg
fails that build rather than picking a winner. Restore with
`git checkout content/index.org`, but then the home collection needs a different output.
Nothing in the weblorg setup changed. publish.el, theme/ and build.py still work as
before, so both builds coexist until one is chosen.
Known difference: the nav renders Home, Salary, Blog, Garden, Tags — explicit source
pages come before generated ones, where the live site orders Salary last.
Diffstat (limited to 'content')
| -rw-r--r-- | content/index.org | 2 | ||||
| -rw-r--r-- | content/org-ssg.toml | 95 | ||||
| -rw-r--r-- | content/styles.css | 23 | ||||
| -rw-r--r-- | content/templates/base.html | 52 | ||||
| -rw-r--r-- | content/templates/home.html | 44 | ||||
| -rw-r--r-- | content/templates/list.html | 13 | ||||
| -rw-r--r-- | content/templates/tags.html | 10 |
7 files changed, 237 insertions, 2 deletions
diff --git a/content/index.org b/content/index.org deleted file mode 100644 index 32e428d..0000000 --- a/content/index.org +++ /dev/null @@ -1,2 +0,0 @@ -#+title: cleberg.net -#+description: Stillness amidst the chaos. diff --git a/content/org-ssg.toml b/content/org-ssg.toml new file mode 100644 index 0000000..d88e309 --- /dev/null +++ b/content/org-ssg.toml @@ -0,0 +1,95 @@ +# org-ssg configuration for cleberg.net. +# +# Lives in content/ because that directory is the site's URL root: content/blog/post.org +# publishes at /blog/post.html. Neither this file nor templates/ is published. +# +# org-ssg serve content -o /tmp/preview # write and preview +# org-ssg build content -o _site --strict # build for real, failing on broken links +# +# This sits alongside the existing weblorg setup (publish.el, theme/) and changes nothing +# about it. Delete this file and content/templates/ to remove org-ssg entirely. + +[site] +title = "cleberg.net" +description = "Stillness amidst the chaos." +language = "en" +# Empty keeps every URL relative, so the site works from a preview directory as well as +# from its real origin. Set it to "https://cleberg.net" when you want canonical links, or +# an RSS feed — a feed is read away from the site that served it, so its links cannot be +# relative. +base_url = "" + +[nav] +# Explicit, because the pages that belong in the nav are not all top-level: /blog/ and +# /garden/ are generated below, and salary/ is a section index one level down. index.org +# is deliberately absent — the layout already links home from the site title, and listing +# it here would print "cleberg.net" twice side by side. Source pages come first in the +# order listed, then the collections that set `nav = true`. +mode = "explicit" +pages = ["salary/index.org"] + +[templates] +dir = "templates" + +[highlight] +theme = "InspiredGitHub" + +[html] +# Level-1 org headings become <h2>, beneath the page title the layout renders as <h1> — +# which is what the current site does too. +heading_offset = 1 +toc = true +section_numbers = false + +# --- Generated pages ------------------------------------------------------------- +# These have no source .org file. weblorg produces the equivalents today through its +# blog-index, garden-index and tags routes. + +# The home page. Generated rather than authored, because it is a hand-written +# introduction *plus* the most recent posts — and the post list is not something to +# maintain by hand. The prose lives in templates/home.html, which is where weblorg keeps +# it today too. +# +# content/index.org was deleted to make room: it held only #+title and #+description, +# both of which are now [site] settings above. Restore it any time with +# `git checkout content/index.org`, but then this collection must output somewhere else — +# two pages cannot claim one URL, and org-ssg fails the build rather than picking a winner. +[[collections]] +source = "blog" +output = "index.html" +template = "home.html" +title = "cleberg.net" +sort = "date" +order = "desc" + +[[collections]] +source = "blog" +output = "blog/index.html" +template = "list.html" +title = "Blog" +sort = "date" +order = "desc" +nav = true + +[[collections]] +source = "garden" +output = "garden/index.html" +template = "list.html" +title = "Garden" +sort = "date" +order = "desc" +nav = true + +# One page per tag, plus the index the live site already has at /tags/. `source` is empty +# so it groups across the whole site rather than one section, which is how #+FILETAGS: is +# used here — tags appear on blog posts and garden notes alike. +[[collections]] +source = "" +group_by = "tags" +output = "tags/{tag}.html" +template = "list.html" +title = "Tagged: {tag}" +index_output = "tags/index.html" +index_template = "tags.html" +index_title = "Tags" +nav = true diff --git a/content/styles.css b/content/styles.css new file mode 100644 index 0000000..19e4711 --- /dev/null +++ b/content/styles.css @@ -0,0 +1,23 @@ +body { max-width: 800px; margin: 0 auto; padding: 1rem; } +a, a:visited { color: #0000ff; } +nav ul { list-style: none; padding: 0; display: flex; flex-direction: row; } +nav ul li { padding-right: 0.5rem;} +img { max-width: 100%; } +.post-list { padding: 0; padding-inline-start: 0; } +.post-list-item { display: flex; list-style: none; align-items: baseline; } +.post-list-item time { padding-right: 0.5rem; white-space: nowrap; } +.post-list-item a { flex-grow: 1; white-space: normal; } +.post-list-year { list-style: none; margin-top: 1rem; margin-bottom: 0.5rem; font-weight: bold; } +.skip-link { display: none; } +footer { margin: 2rem 0;} +pre, blockquote { margin: 1rem 0; padding: 0.5rem; background-color: #eee; } +pre { overflow: auto; white-space: pre; } +blockquote p { margin: 0; margin-bottom: 1rem; } +blockquote p:last-child { margin-bottom: 0; } +code { color: #942192; } +@media (prefers-color-scheme: dark) { + body { background-color: #181a1b; color: #cccccc; } + a, a:visited { color: #68A9F8; } + code { color: #ff68e1; } + pre, blockquote { background-color: black; } +} diff --git a/content/templates/base.html b/content/templates/base.html new file mode 100644 index 0000000..19c5509 --- /dev/null +++ b/content/templates/base.html @@ -0,0 +1,52 @@ +{# Page layout for org-ssg. + + Styling comes from styles.css, a verbatim copy of theme/static/styles.css — the + stylesheet weblorg already serves. org-ssg publishes assets from inside its source + directory, so the copy lives here; `diff content/styles.css theme/static/styles.css` + should stay empty, or consolidate the two if you migrate for real. + + Available here: page (.title .url .date .date_iso .tags .excerpt .toc .keywords), + site, nav, root, stylesheet. See the org-ssg guide chapter on Templates. #} +<!DOCTYPE html> +<html lang="{{ site.language }}"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<title>{{ page.title }} · {{ site.title }}</title> +{%- if site.base_url %} +<link rel="canonical" href="{{ page.url | absolute }}"> +{%- endif %} +{%- if page.excerpt %} +<meta name="description" content="{{ page.excerpt | truncate(150) }}"> +{%- endif %} +<link rel="stylesheet" href="{{ root }}styles.css"> +{%- if stylesheet %} +<link rel="stylesheet" href="{{ stylesheet }}"> +{%- endif %} +</head> +<body> +<header> +<nav> +<ul> +<li><a href="{{ root }}index.html">{{ site.title }}</a></li> +{%- for item in nav %} +<li><a href="{{ item.url }}">{{ item.title }}</a></li> +{%- endfor %} +</ul> +</nav> +</header> +<main> +<h1>{{ page.title }}</h1> +{%- if page.date_iso %} +<p><time datetime="{{ page.date_iso }}">{{ page.date_iso }}</time></p> +{%- endif %} +{%- if page.tags %} +<p>{% for tag in page.tags %}<a href="{{ root }}tags/{{ tag }}.html">#{{ tag }}</a> {% endfor %}</p> +{%- endif %} +{% block content %}{{ body | safe }}{% endblock %} +</main> +<footer> +<p><a href="{{ root }}index.html">{{ site.title }}</a> — {{ site.description }}</p> +</footer> +</body> +</html> diff --git a/content/templates/home.html b/content/templates/home.html new file mode 100644 index 0000000..be5a0e6 --- /dev/null +++ b/content/templates/home.html @@ -0,0 +1,44 @@ +{# The home page: authored prose plus the most recent posts. + + A generated page, so it has no source .org file — `pages` holds the blog collection's + entries, newest first, and the prose lives here. This mirrors what weblorg's + theme/templates/index.html does today. #} +{% extends "base.html" %} +{% block content %} +<section> +<p>[ <a href="https://krz.sh">krz</a> · <a href="https://audit-labs.dev">audit labs</a> ]</p> +<p>Privacy · Self-Hosting · iOS</p> +<p>I build tools, write about systems, and run my own infrastructure. Focused on privacy, +user control, and long-term utility.</p> +<p><a href="{{ root }}uses/index.html">Uses</a> · <a href="{{ root }}now/index.html">Now</a></p> +</section> + +<section> +<h2>Recent Posts</h2> +<p>Things I’ve written recently.</p> +<ul class="post-list"> +{%- for entry in pages %} +{%- if loop.index <= 3 %} +<li class="post-list-item"> +{%- if entry.date_iso %}<time datetime="{{ entry.date_iso }}">{{ entry.date_iso }}</time>{% endif %} +<a href="{{ root }}{{ entry.url }}">{{ entry.title }}</a> +</li> +{%- endif %} +{%- endfor %} +</ul> +<p><a href="{{ root }}blog/index.html">All Posts →</a></p> +</section> + +<section> +<h2>Elsewhere</h2> +<p>Places to find me online.</p> +<ul> +<li>cgit (primary): <a href="https://git.krz.sh">~cmc</a></li> +<li>GitHub (mirror): <a href="https://github.com/ccleberg">@ccleberg</a></li> +<li>Email: <a href="mailto:[email protected]">[email protected]</a></li> +<li>Lemmy: <a href="https://r.nf/u/cmc">@cmc</a></li> +<li>Mastodon: <a href="https://c.im/@cmc">@cmc</a></li> +<li>Pixelfed: <a href="https://gram.social/cmc">@cmc</a></li> +</ul> +</section> +{% endblock %} diff --git a/content/templates/list.html b/content/templates/list.html new file mode 100644 index 0000000..6ff9968 --- /dev/null +++ b/content/templates/list.html @@ -0,0 +1,13 @@ +{# A listing page: the blog index, the garden index, and each tag page. + Uses the .post-list / .post-list-item classes styles.css already defines. #} +{% extends "base.html" %} +{% block content %} +<ul class="post-list"> +{%- for entry in pages %} +<li class="post-list-item"> +{%- if entry.date_iso %}<time datetime="{{ entry.date_iso }}">{{ entry.date_iso }}</time>{% endif %} +<a href="{{ root }}{{ entry.url }}">{{ entry.title }}</a> +</li> +{%- endfor %} +</ul> +{% endblock %} diff --git a/content/templates/tags.html b/content/templates/tags.html new file mode 100644 index 0000000..9702f59 --- /dev/null +++ b/content/templates/tags.html @@ -0,0 +1,10 @@ +{# The tag index at /tags/. Receives `groups` — every tag with its count — rather than + `pages`, because it lists tags and not posts. #} +{% extends "base.html" %} +{% block content %} +<ul> +{%- for tag in groups %} +<li><a href="{{ root }}{{ tag.url }}">{{ tag.name }}</a> ({{ tag.count }})</li> +{%- endfor %} +</ul> +{% endblock %} |
