<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>aphid</title>
  <link href="https://aphid.lhelge.se/feed.xml" rel="self" type="application/atom+xml"/>
  <link href="https://aphid.lhelge.se/" rel="alternate" type="text/html"/>
  <id>https://aphid.lhelge.se/</id>
  <updated>2026-05-19T00:00:00+00:00</updated>
  <subtitle>A CLI static site generator for blogs, wikis, and pages</subtitle>
  <entry>
    <title>aphid 0.3.0</title>
    <link href="https://aphid.lhelge.se/blog/v0-3/" rel="alternate" type="text/html"/>
    <id>https://aphid.lhelge.se/blog/v0-3/</id>
    <published>2026-05-19T00:00:00+00:00</published>
    <updated>2026-05-19T00:00:00+00:00</updated>
    <author>
      <name>LHelge</name>
    </author>
    <summary type="text">Rich wiki categories with descriptions and icons, a card-based wiki index, and an optional wiki intro page — the wiki gets a proper landing experience.</summary>
    <content type="html">&lt;p&gt;aphid 0.3.0 reworks the wiki index into a proper landing page. Categories gain descriptions and icons, the index renders them as cards instead of a flat list, and an optional &lt;code&gt;wiki.md&lt;/code&gt; file lets you write introductory text above the cards.&lt;/p&gt;
&lt;h2 id=&quot;rich-wiki-categories&quot;&gt;Rich wiki categories&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;wiki_categories&lt;/code&gt; in &lt;code&gt;aphid.toml&lt;/code&gt; is no longer a flat list of strings. Each category is now a table with an optional description and icon:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-table hl-array hl-begin hl-toml&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-section hl-toml&quot;&gt;wiki_categories&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-table hl-array hl-end hl-toml&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;Getting Started&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;Installation, configuration, and first steps.&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;icon&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;/static/wiki/getting-started.svg&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;hl-punctuation hl-definition hl-table hl-array hl-begin hl-toml&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-section hl-toml&quot;&gt;wiki_categories&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-table hl-array hl-end hl-toml&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;Content&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;Writing blog posts, wiki pages, and standalone pages.&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;icon&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;/static/wiki/content.svg&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Field&lt;/th&gt;&lt;th&gt;Required&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;name&lt;/code&gt;&lt;/td&gt;&lt;td&gt;yes&lt;/td&gt;&lt;td&gt;Category name, matched against frontmatter &lt;code&gt;category&lt;/code&gt; values&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;description&lt;/code&gt;&lt;/td&gt;&lt;td&gt;no&lt;/td&gt;&lt;td&gt;Short blurb shown on the wiki index card&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;icon&lt;/code&gt;&lt;/td&gt;&lt;td&gt;no&lt;/td&gt;&lt;td&gt;Root-relative URL path to an SVG icon&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The &lt;code&gt;icon&lt;/code&gt; path is root-relative (e.g. &lt;code&gt;&quot;/static/wiki/foo.svg&quot;&lt;/code&gt;), consistent with &lt;code&gt;favicon&lt;/code&gt; and &lt;code&gt;social_image&lt;/code&gt;. Place your SVGs under &lt;code&gt;static/&lt;/code&gt; and reference their served path.&lt;/p&gt;
&lt;p&gt;This is a &lt;strong&gt;breaking change&lt;/strong&gt; — the old format:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-toml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;wiki_categories&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-punctuation hl-definition hl-array hl-begin hl-toml&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;Getting Started&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &amp;quot;Content&amp;quot;]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;must be migrated to the array-of-tables form shown above. If you only need names, omit &lt;code&gt;description&lt;/code&gt; and &lt;code&gt;icon&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-table hl-array hl-begin hl-toml&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-section hl-toml&quot;&gt;wiki_categories&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-table hl-array hl-end hl-toml&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;Getting Started&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;hl-punctuation hl-definition hl-table hl-array hl-begin hl-toml&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-section hl-toml&quot;&gt;wiki_categories&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-table hl-array hl-end hl-toml&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;Content&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;card-based-wiki-index&quot;&gt;Card-based wiki index&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;wiki_index.html&lt;/code&gt; template now receives richer category objects:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Variable&lt;/th&gt;&lt;th&gt;Type&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;categories[].name&lt;/code&gt;&lt;/td&gt;&lt;td&gt;string&lt;/td&gt;&lt;td&gt;Category name&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;categories[].description&lt;/code&gt;&lt;/td&gt;&lt;td&gt;string?&lt;/td&gt;&lt;td&gt;From config&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;categories[].icon&lt;/code&gt;&lt;/td&gt;&lt;td&gt;string?&lt;/td&gt;&lt;td&gt;From config&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;categories[].pages&lt;/code&gt;&lt;/td&gt;&lt;td&gt;list&lt;/td&gt;&lt;td&gt;Pages in this category (&lt;code&gt;{title, url}&lt;/code&gt;)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The bundled theme and default theme both render these as cards with the icon, name, description, and a list of page links. Custom themes can use as much or as little of the new data as they like — &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;pages&lt;/code&gt; are always present, just as before.&lt;/p&gt;
&lt;p&gt;The same enriched shape is available in the &lt;code&gt;wiki_categories&lt;/code&gt; variable on &lt;code&gt;wiki_page.html&lt;/code&gt;, so sidebar navigation can also show icons and descriptions if desired.&lt;/p&gt;
&lt;h2 id=&quot;wiki-intro-page&quot;&gt;Wiki intro page&lt;/h2&gt;
&lt;p&gt;Create a &lt;code&gt;content/wiki.md&lt;/code&gt; (no frontmatter needed) to add introductory content above the category cards on the wiki index. The file is rendered through the full markdown pipeline — wiki-links, syntax highlighting, and all other extensions work as expected.&lt;/p&gt;
&lt;p&gt;The rendered HTML is exposed to &lt;code&gt;wiki_index.html&lt;/code&gt; as &lt;code&gt;wiki_intro.content&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-text hl-plain&quot;&gt;{% if wiki_intro %}
&amp;lt;div class=&amp;quot;wiki-intro&amp;quot;&amp;gt;
{{ wiki_intro.content | safe }}
&amp;lt;/div&amp;gt;
{% endif %}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This follows the same pattern as &lt;code&gt;home.md&lt;/code&gt; and &lt;code&gt;404.md&lt;/code&gt; — a bodyless content file (no frontmatter) whose rendered HTML is injected into the corresponding template.&lt;/p&gt;
&lt;h2 id=&quot;upgrading&quot;&gt;Upgrading&lt;/h2&gt;&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-shell hl-bash&quot;&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;cargo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; install aphid&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;locked&lt;/span&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;force&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;version&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The only breaking change is the &lt;code&gt;wiki_categories&lt;/code&gt; config format. If you were using the old list form, convert each entry to a &lt;code&gt;[[wiki_categories]]&lt;/code&gt; table with a &lt;code&gt;name&lt;/code&gt; field. Custom themes that loop over &lt;code&gt;categories&lt;/code&gt; on &lt;code&gt;wiki_index.html&lt;/code&gt; continue to work unchanged — the &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;pages&lt;/code&gt; fields keep their previous shape, with &lt;code&gt;description&lt;/code&gt; and &lt;code&gt;icon&lt;/code&gt; added alongside.&lt;/p&gt;
&lt;p&gt;After upgrading, run &lt;code&gt;aphid agent &amp;lt;your-tool&amp;gt;&lt;/code&gt; to refresh skill files with the updated configuration documentation.&lt;/p&gt;
&lt;p&gt;See also: &lt;a href=&quot;https://aphid.lhelge.se/wiki/configuration/&quot;&quot; class=&quot;wikilink&quot;&gt;Configuration&lt;/a&gt;, &lt;a href=&quot;https://aphid.lhelge.se/wiki/themes/#wiki-index-html&quot;&quot; class=&quot;wikilink&quot;&gt;Themes &amp;gt; wiki-index-html&lt;/a&gt;, &lt;a href=&quot;https://aphid.lhelge.se/wiki/themes/#wiki-page-html&quot;&quot; class=&quot;wikilink&quot;&gt;Themes &amp;gt; wiki-page-html&lt;/a&gt;.&lt;/p&gt;
</content>
    <category term="aphid"/>
    <category term="release"/>
    <category term="breaking"/>
    <category term="wiki"/>
    <category term="themes"/>
  </entry>
  <entry>
    <title>aphid 0.2.2</title>
    <link href="https://aphid.lhelge.se/blog/v0-2-2/" rel="alternate" type="text/html"/>
    <id>https://aphid.lhelge.se/blog/v0-2-2/</id>
    <published>2026-05-16T00:00:00+00:00</published>
    <updated>2026-05-16T00:00:00+00:00</updated>
    <author>
      <name>LHelge</name>
    </author>
    <summary type="text">AI-agent skill scaffolding via `aphid agent`, a popularity-sorted tag cloud on the home page, and a clearer tag page that splits blog posts and wiki pages into separate sections.</summary>
    <content type="html">&lt;p&gt;aphid 0.2.2 ships AI-agent skill files you can drop into any project, plus two theme-side wins: a popularity-sorted tag cloud variable for the home page, and a tag page that groups blog posts and wiki pages separately.&lt;/p&gt;
&lt;h2 id=&quot;ai-agent-skills-with-aphid-agent&quot;&gt;AI-agent skills with &lt;code&gt;aphid agent&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;A new subcommand scaffolds project-level instruction files for AI coding agents:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-shell hl-bash&quot;&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; agent claude     &lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-comment hl-begin hl-shell&quot;&gt;#&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt; writes .claude/skills/aphid-content + .claude/skills/aphid-theme&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; agent copilot    &lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-comment hl-begin hl-shell&quot;&gt;#&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt; writes .github/copilot-instructions.md&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; agent codex      &lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-comment hl-begin hl-shell&quot;&gt;#&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt; writes AGENTS.md&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; agent            &lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-comment hl-begin hl-shell&quot;&gt;#&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt; same as `aphid agent codex` — generic AGENTS.md&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The files describe everything an agent needs to write content or design a theme for your site: the frontmatter shape for each content type, the markdown extensions aphid supports, the Tera template variables exposed to themes, the layout of the &lt;code&gt;static/&lt;/code&gt; directory, and so on. The reference content is embedded in the aphid binary, so re-running the same command after upgrading aphid refreshes the skill files with any new feature documentation.&lt;/p&gt;
&lt;p&gt;For Claude Code, the command writes two distinct skills — &lt;code&gt;aphid-content&lt;/code&gt; for writing and &lt;code&gt;aphid-theme&lt;/code&gt; for design — so the agent loads only what’s relevant to the task at hand. For other tools it writes a single &lt;code&gt;AGENTS.md&lt;/code&gt; or the tool-specific equivalent (&lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; for GitHub Copilot, etc.). The generic &lt;code&gt;AGENTS.md&lt;/code&gt; is also recognised by Aider, Goose, and current Cursor versions.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;aphid new&lt;/code&gt; and &lt;code&gt;aphid init&lt;/code&gt; accept an &lt;code&gt;--agent &amp;lt;tool&amp;gt;&lt;/code&gt; flag to scaffold these files at the same time as the rest of the site:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-shell hl-bash&quot;&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; new my-blog&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;agent&lt;/span&gt; claude&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; init&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;agent          &lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-comment hl-begin hl-shell&quot;&gt;#&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt; generic AGENTS.md (tool defaults to codex)&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The main instructions file is preserved on re-run so you can extend it with project-specific guidance; the per-skill reference files are always overwritten. See &lt;a href=&quot;https://aphid.lhelge.se/wiki/cli/#aphid-agent&quot;&quot; class=&quot;wikilink&quot;&gt;CLI reference &amp;gt; aphid-agent&lt;/a&gt; for the full command reference, and &lt;a href=&quot;https://aphid.lhelge.se/wiki/ai-assisted-writing/&quot;&quot; class=&quot;wikilink&quot;&gt;AI-Assisted Writing&lt;/a&gt; / &lt;a href=&quot;https://aphid.lhelge.se/wiki/ai-assisted-design/&quot;&quot; class=&quot;wikilink&quot;&gt;AI-Assisted Design&lt;/a&gt; for the content of each skill.&lt;/p&gt;
&lt;h2 id=&quot;home-page-tag-cloud&quot;&gt;Home page tag cloud&lt;/h2&gt;
&lt;p&gt;Themes can now render a tag cloud on the home page using a new &lt;code&gt;popular_tags&lt;/code&gt; variable on the &lt;code&gt;home.html&lt;/code&gt; context:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-text hl-plain&quot;&gt;{% for tag in popular_tags %}
&amp;lt;a href=&amp;quot;/tags/{{ tag.slug }}/&amp;quot;&amp;gt;{{ tag.name }} ({{ tag.count }})&amp;lt;/a&amp;gt;
{% endfor %}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every tag used across blog and wiki content is included, sorted by descending count then ascending name. Counts match the &lt;code&gt;/tags/&lt;/code&gt; index — a tag’s number is identical wherever it appears on the site. For a top-N cloud, slice with &lt;code&gt;popular_tags | slice(end=20)&lt;/code&gt; in Tera; weighting font sizes by count is left as a theme decision.&lt;/p&gt;
&lt;p&gt;The bundled docs theme renders the cloud as a “Browse by topic” section under the latest posts on the home page.&lt;/p&gt;
&lt;h2 id=&quot;tag-pages-split-blog-and-wiki-content&quot;&gt;Tag pages split blog and wiki content&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;tag.html&lt;/code&gt; used to receive a single mixed &lt;code&gt;posts&lt;/code&gt; list. It now receives two:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Variable&lt;/th&gt;&lt;th&gt;Contents&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;blog_posts&lt;/code&gt;&lt;/td&gt;&lt;td&gt;All blog posts carrying the tag&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;wiki_pages&lt;/code&gt;&lt;/td&gt;&lt;td&gt;All wiki pages carrying the tag&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Both share the post-entry shape from &lt;code&gt;blog_index.html&lt;/code&gt;. If a tag is exclusive to one kind of content the other list is empty — guard both with a length check:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-text hl-plain&quot;&gt;{% if blog_posts | length &amp;gt; 0 %}
&amp;lt;section&amp;gt;
  &amp;lt;h2&amp;gt;Blog&amp;lt;/h2&amp;gt;
  {% for post in blog_posts %}…{% endfor %}
&amp;lt;/section&amp;gt;
{% endif %}
{% if wiki_pages | length &amp;gt; 0 %}
&amp;lt;section&amp;gt;
  &amp;lt;h2&amp;gt;Wiki&amp;lt;/h2&amp;gt;
  {% for post in wiki_pages %}…{% endfor %}
&amp;lt;/section&amp;gt;
{% endif %}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the small breaking change in 0.2.2: custom themes that previously looped over &lt;code&gt;posts&lt;/code&gt; on &lt;code&gt;tag.html&lt;/code&gt; need to switch to the two new variables.&lt;/p&gt;
&lt;h2 id=&quot;tag-pages-no-longer-paginate&quot;&gt;Tag pages no longer paginate&lt;/h2&gt;
&lt;p&gt;Tag pages used to chunk with &lt;code&gt;posts_per_page&lt;/code&gt; and reuse the blog-index &lt;code&gt;pagination.html&lt;/code&gt; partial with its chronological “Newer / Older” labels — semantics that fit time-ordered blog content but never wiki references. And in practice tag listings rarely accumulate enough items to need chunking.&lt;/p&gt;
&lt;p&gt;So 0.2.2 drops pagination from tag pages entirely. The full list of tagged content is rendered on the canonical &lt;code&gt;/tags/&amp;lt;slug&amp;gt;/&lt;/code&gt; URL — no &lt;code&gt;page/N/&lt;/code&gt; subdirectories — and &lt;code&gt;pagination&lt;/code&gt; is no longer present on the &lt;code&gt;tag.html&lt;/code&gt; context. The &lt;code&gt;pagination.html&lt;/code&gt; include still works elsewhere (the blog index keeps its chronological pagination); it’s just never invoked from &lt;code&gt;tag.html&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If your custom theme guards the include with &lt;code&gt;{% if pagination %}{% include &quot;pagination.html&quot; %}{% endif %}&lt;/code&gt; on &lt;code&gt;tag.html&lt;/code&gt;, the conditional becomes always-false and the include is silently skipped. Drop the line when you’re next editing the template.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&quot;https://aphid.lhelge.se/wiki/themes/#tag-html&quot;&quot; class=&quot;wikilink&quot;&gt;Themes &amp;gt; tag-html&lt;/a&gt; for the full updated variable list and &lt;a href=&quot;https://aphid.lhelge.se/wiki/pagination/&quot;&quot; class=&quot;wikilink&quot;&gt;Pagination&lt;/a&gt; for how pagination still works on the blog index.&lt;/p&gt;
&lt;h2 id=&quot;upgrading&quot;&gt;Upgrading&lt;/h2&gt;&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-shell hl-bash&quot;&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;cargo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; install aphid&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;locked&lt;/span&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;force&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;version&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The only breaking change is &lt;code&gt;tag.html&lt;/code&gt;. Bundled themes are already updated. For custom themes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Replace the &lt;code&gt;posts&lt;/code&gt; loop with two guarded sections for &lt;code&gt;blog_posts&lt;/code&gt; and &lt;code&gt;wiki_pages&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Drop the &lt;code&gt;{% include &quot;pagination.html&quot; %}&lt;/code&gt; line — &lt;code&gt;pagination&lt;/code&gt; is no longer set on the context.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Everything else is additive: &lt;code&gt;popular_tags&lt;/code&gt; on &lt;code&gt;home.html&lt;/code&gt; is opt-in, and &lt;code&gt;aphid agent&lt;/code&gt; is a new command that doesn’t touch any existing files until you ask it to. After upgrading, run &lt;code&gt;aphid agent &amp;lt;your-tool&amp;gt;&lt;/code&gt; once to refresh any previously-generated skill files with the new feature documentation.&lt;/p&gt;
&lt;p&gt;See also: &lt;a href=&quot;https://aphid.lhelge.se/wiki/ai-assisted-writing/&quot;&quot; class=&quot;wikilink&quot;&gt;AI-Assisted Writing&lt;/a&gt;, &lt;a href=&quot;https://aphid.lhelge.se/wiki/ai-assisted-design/&quot;&quot; class=&quot;wikilink&quot;&gt;AI-Assisted Design&lt;/a&gt;, &lt;a href=&quot;https://aphid.lhelge.se/wiki/themes/#home-html&quot;&quot; class=&quot;wikilink&quot;&gt;Themes &amp;gt; home-html&lt;/a&gt;, &lt;a href=&quot;https://aphid.lhelge.se/wiki/themes/#tag-html&quot;&quot; class=&quot;wikilink&quot;&gt;Themes &amp;gt; tag-html&lt;/a&gt;.&lt;/p&gt;
</content>
    <category term="aphid"/>
    <category term="release"/>
    <category term="breaking"/>
    <category term="ai"/>
    <category term="themes"/>
  </entry>
  <entry>
    <title>aphid 0.2.1</title>
    <link href="https://aphid.lhelge.se/blog/v0-2-1/" rel="alternate" type="text/html"/>
    <id>https://aphid.lhelge.se/blog/v0-2-1/</id>
    <published>2026-05-15T00:00:00+00:00</published>
    <updated>2026-05-15T00:00:00+00:00</updated>
    <author>
      <name>LHelge</name>
    </author>
    <summary type="text">A content-polish release. Wiki-links now accept `[[page#section]]` anchors, headings take `{#custom-id}` overrides, author config gains a dedicated `link` field, every page ships OpenGraph + Twitter card meta tags, and blog posts expose a reading-time estimate.</summary>
    <content type="html">&lt;p&gt;aphid 0.2.1 is a small content-polish release. Five additions, all backward-compatible: deeper wiki-links, stable heading anchors, a cleaner way to point an author at a profile URL, social-card meta tags emitted on every page so shared links get proper previews, and reading-time estimates on blog posts.&lt;/p&gt;
&lt;h2 id=&quot;wiki-link-anchors&quot;&gt;Wiki-link anchors&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://aphid.lhelge.se/wiki/wiki-links/&quot;&quot; class=&quot;wikilink&quot;&gt;Wiki-links&lt;/a&gt; now accept an in-page anchor after the slug:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-text hl-plain&quot;&gt;[[configuration#authors]]
[[configuration#authors|the authors section]]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The anchor text is slugified the same way as auto-generated heading ids, so &lt;code&gt;[[page#Hello World]]&lt;/code&gt; resolves to &lt;code&gt;#hello-world&lt;/code&gt;. A bare cross-page anchor renders as &lt;code&gt;Page Title &amp;gt; section&lt;/code&gt; so the reader knows which page they’re heading to; pipe-alias to override.&lt;/p&gt;
&lt;p&gt;Same-page anchors work too:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-text hl-plain&quot;&gt;Jump to [[#summary]].
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Backlinks are unaffected — the anchor portion is stripped before the link is recorded, so backlinks still aggregate at page granularity.&lt;/p&gt;
&lt;h2 id=&quot;custom-heading-ids&quot;&gt;Custom heading IDs&lt;/h2&gt;
&lt;p&gt;Append &lt;code&gt;{#custom-id}&lt;/code&gt; to any heading to override its auto-generated anchor:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-text hl-html hl-markdown&quot;&gt;&lt;span class=&quot;hl-meta hl-block-level hl-markdown&quot;&gt;&lt;span class=&quot;hl-markup hl-heading hl-2 hl-markdown&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-heading hl-begin hl-markdown&quot;&gt;##&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;hl-markup hl-heading hl-2 hl-markdown&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-section hl-markdown&quot;&gt;Configuration reference {#config-ref}&lt;/span&gt;&lt;span class=&quot;hl-meta hl-whitespace hl-newline hl-markdown&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Renders as &lt;code&gt;&amp;lt;h3 id=&quot;config-ref&quot;&amp;gt;&lt;/code&gt;. Custom ids are used verbatim — no lowercasing, no slug normalization — so &lt;code&gt;{#API_v2.1}&lt;/code&gt; stays &lt;code&gt;API_v2.1&lt;/code&gt;. Custom and auto ids share the same per-page namespace, so collisions still get &lt;code&gt;-2&lt;/code&gt;, &lt;code&gt;-3&lt;/code&gt;, … suffixes.&lt;/p&gt;
&lt;p&gt;The two features compose. Give a heading a &lt;a href=&quot;https://aphid.lhelge.se/wiki/markdown/#custom-ids&quot;&quot; class=&quot;wikilink&quot;&gt;custom id&lt;/a&gt;, then target it from elsewhere with &lt;code&gt;[[page#stable-id]]&lt;/code&gt; — rephrasing the heading text won’t break the link.&lt;/p&gt;
&lt;h2 id=&quot;author-link-field&quot;&gt;Author &lt;code&gt;link&lt;/code&gt; field&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;[[authors]]&lt;/code&gt; entries now support an explicit &lt;code&gt;link&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-table hl-array hl-begin hl-toml&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-section hl-toml&quot;&gt;authors&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-table hl-array hl-end hl-toml&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;Alice&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;link&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;https://alice.example.com&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;email&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;alice@example.com&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Templates receive &lt;code&gt;author.link&lt;/code&gt; as the URL for the author’s profile. When &lt;code&gt;link&lt;/code&gt; is unset but &lt;code&gt;email&lt;/code&gt; is, &lt;code&gt;author.link&lt;/code&gt; falls back to &lt;code&gt;mailto:{email}&lt;/code&gt; — matching the previous behaviour, so existing configs keep working unchanged. When neither is set, the author name renders as plain text.&lt;/p&gt;
&lt;p&gt;The bundled themes wrap the author avatar and name in &lt;code&gt;&amp;lt;a href=&quot;{{ author.link }}&quot;&amp;gt;&lt;/code&gt; when present. Custom themes that referenced &lt;code&gt;author.email&lt;/code&gt; directly should switch to &lt;code&gt;author.link&lt;/code&gt;; the value is the same in the email-only case.&lt;/p&gt;
&lt;h2 id=&quot;social-card-meta-tags&quot;&gt;Social card meta tags&lt;/h2&gt;
&lt;p&gt;Every page now ships OpenGraph and Twitter card meta tags in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; — so a link shared in Slack, Discord, Mastodon, iMessage, Bluesky, etc. renders a preview card instead of a bare URL.&lt;/p&gt;
&lt;p&gt;Blog posts mark themselves up as &lt;code&gt;og:type=article&lt;/code&gt; and emit &lt;code&gt;article:published_time&lt;/code&gt;, &lt;code&gt;article:modified_time&lt;/code&gt;, &lt;code&gt;article:author&lt;/code&gt;, and &lt;code&gt;article:tag&lt;/code&gt; tags from frontmatter. Other pages mark themselves up as &lt;code&gt;og:type=website&lt;/code&gt;. Titles, descriptions, and images fall back through page → site config sensibly:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Tag&lt;/th&gt;&lt;th&gt;Blog post source&lt;/th&gt;&lt;th&gt;Other pages&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;og:title&lt;/code&gt;&lt;/td&gt;&lt;td&gt;frontmatter &lt;code&gt;title&lt;/code&gt;&lt;/td&gt;&lt;td&gt;page &lt;code&gt;title&lt;/code&gt;, then &lt;code&gt;site_title&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;og:description&lt;/code&gt;&lt;/td&gt;&lt;td&gt;frontmatter &lt;code&gt;description&lt;/code&gt;&lt;/td&gt;&lt;td&gt;site &lt;code&gt;description&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;og:image&lt;/code&gt;&lt;/td&gt;&lt;td&gt;frontmatter &lt;code&gt;image&lt;/code&gt;&lt;/td&gt;&lt;td&gt;site &lt;code&gt;social_image&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;og:url&lt;/code&gt;&lt;/td&gt;&lt;td&gt;absolute URL of the post&lt;/td&gt;&lt;td&gt;absolute URL of the page&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;A new optional config field sets the site-wide image fallback:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-toml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;social_image&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;/static/social-card.png&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;   &lt;span class=&quot;hl-comment hl-line hl-number-sign hl-toml&quot;&gt;# root-relative URL or absolute URL&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Recommended dimensions are 1200×630 px — the &lt;code&gt;summary_large_image&lt;/code&gt; Twitter card format that most platforms render best. When no image is configured anywhere, the card downgrades to &lt;code&gt;summary&lt;/code&gt; and the &lt;code&gt;og:image&lt;/code&gt; / &lt;code&gt;twitter:image&lt;/code&gt; tags are omitted.&lt;/p&gt;
&lt;p&gt;Custom themes inherit the behaviour automatically by extending &lt;code&gt;base.html&lt;/code&gt;. To override the type or add per-page tags, override the &lt;code&gt;og_type&lt;/code&gt; and &lt;code&gt;article_meta&lt;/code&gt; blocks — see &lt;a href=&quot;https://aphid.lhelge.se/wiki/themes/&quot;&quot; class=&quot;wikilink&quot;&gt;Themes&lt;/a&gt; for the full block list.&lt;/p&gt;
&lt;h2 id=&quot;reading-time&quot;&gt;Reading time&lt;/h2&gt;
&lt;p&gt;Blog post templates now receive a &lt;code&gt;reading_time_minutes&lt;/code&gt; variable — an integer estimate based on word-count of the body, divided by the assumed reading speed, rounded up (minimum 1). The bundled themes render it inline with the publication date:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-text hl-plain&quot;&gt;&amp;lt;span&amp;gt;{{ reading_time_minutes }} min read&amp;lt;/span&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The reading speed defaults to 200 wpm (conservative, suits technical writing with code samples) and is tunable via a new &lt;code&gt;reading_wpm&lt;/code&gt; config field — raise it for prose-heavy sites:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-toml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;reading_wpm&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-constant hl-numeric hl-integer hl-decimal hl-toml&quot;&gt;250&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Custom themes can render the variable however they like. See &lt;a href=&quot;https://aphid.lhelge.se/wiki/themes/&quot;&quot; class=&quot;wikilink&quot;&gt;Themes&lt;/a&gt; for the full per-template variable list.&lt;/p&gt;
&lt;h2 id=&quot;upgrading&quot;&gt;Upgrading&lt;/h2&gt;&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-shell hl-bash&quot;&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;cargo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; install aphid&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;locked&lt;/span&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;force&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;version&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One small config tweak: author &lt;code&gt;image&lt;/code&gt; paths no longer get a magic &lt;code&gt;/static/&lt;/code&gt; prefix — write them as &lt;code&gt;/static/authors/alice.jpg&lt;/code&gt; (the same convention blog hero images and &lt;code&gt;favicon&lt;/code&gt; use). The new &lt;code&gt;social_image&lt;/code&gt; follows the same rule. Custom themes that read &lt;code&gt;author.email&lt;/code&gt; should also switch to &lt;code&gt;author.link&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;See also: &lt;a href=&quot;https://aphid.lhelge.se/wiki/wiki-links/&quot;&quot; class=&quot;wikilink&quot;&gt;Wiki Links&lt;/a&gt;, &lt;a href=&quot;https://aphid.lhelge.se/wiki/markdown/#custom-ids&quot;&quot; class=&quot;wikilink&quot;&gt;Markdown &amp;gt; custom-ids&lt;/a&gt;, &lt;a href=&quot;https://aphid.lhelge.se/wiki/configuration/&quot;&quot; class=&quot;wikilink&quot;&gt;Configuration&lt;/a&gt;.&lt;/p&gt;
</content>
    <category term="aphid"/>
    <category term="release"/>
    <category term="content"/>
    <category term="markdown"/>
  </entry>
  <entry>
    <title>aphid 0.2.0</title>
    <link href="https://aphid.lhelge.se/blog/v0-2/" rel="alternate" type="text/html"/>
    <id>https://aphid.lhelge.se/blog/v0-2/</id>
    <published>2026-05-07T00:00:00+00:00</published>
    <updated>2026-05-12T00:00:00+00:00</updated>
    <author>
      <name>LHelge</name>
    </author>
    <summary type="text">A theming refresh. The per-page template variables are split into three kind-specific shapes, dropping fields each template never used. Wiki pages gain a per-page category, the &quot;uncategorised&quot; default moves from the theme into config, and the dev server hot-reloads favicon edits.</summary>
    <content type="html">&lt;p&gt;aphid 0.2.0 is a theming refresh. Your content builds the same as it did before — blog posts still publish, wiki-links still resolve, URLs are unchanged. What’s changed is which variables show up in which templates, plus a couple of small dev-server quality-of-life wins. If you’re using the bundled themes unmodified, you can upgrade with no edits; if you’ve forked or written your own theme, read on.&lt;/p&gt;
&lt;h2 id=&quot;why&quot;&gt;Why&lt;/h2&gt;
&lt;p&gt;Templates used to receive a single per-page context object with every conceivable field on it — author, image, description, category, backlinks, the works. Most fields were blog-only or wiki-only, populated as empty for the kinds that didn’t need them, and gated by &lt;code&gt;{% if … %}&lt;/code&gt; in the templates. That meant template authors had to remember which fields were “real” on which page kind, and dead fields silently sat there forever.&lt;/p&gt;
&lt;p&gt;This release splits the per-page context into three shapes — one for blog posts, one for wiki pages, one for standalone pages — each carrying only the variables its template actually uses.&lt;/p&gt;
&lt;h2 id=&quot;theme-changes-what-to-update&quot;&gt;Theme changes — what to update&lt;/h2&gt;
&lt;p&gt;The bundled themes have been updated. If you’ve forked or written your own theme, here’s what to change.&lt;/p&gt;
&lt;h3 id=&quot;wiki-page-html-gains-category&quot;&gt;&lt;code&gt;wiki_page.html&lt;/code&gt; gains &lt;code&gt;category&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Wiki pages now expose a per-page &lt;code&gt;category&lt;/code&gt; variable for templates to render (e.g. as a breadcrumb or header label). Pages without an explicit &lt;code&gt;category&lt;/code&gt; in frontmatter fall back to &lt;code&gt;wiki_default_category&lt;/code&gt; (default &lt;code&gt;&quot;Other&quot;&lt;/code&gt;), so the field is always non-empty.&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-text hl-html hl-basic&quot;&gt;&lt;span class=&quot;hl-meta hl-tag hl-block hl-any hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-begin hl-html&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-block hl-any hl-html&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-end hl-html&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;hl-meta hl-tag hl-block hl-any hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-begin hl-html&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-block hl-any hl-html&quot;&gt;h1&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-end hl-html&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;{{ title }}&lt;span class=&quot;hl-meta hl-tag hl-block hl-any hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-begin hl-html&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-block hl-any hl-html&quot;&gt;h1&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-end hl-html&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;hl-meta hl-tag hl-block hl-any hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-begin hl-html&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-block hl-any hl-html&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;hl-meta hl-attribute-with-value hl-class hl-html&quot;&gt;&lt;span class=&quot;hl-entity hl-other hl-attribute-name hl-class hl-html&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-html&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-attribute-with-value hl-class hl-html&quot;&gt;&lt;span class=&quot;hl-string hl-quoted hl-double hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-html&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-attribute-with-value hl-class hl-html&quot;&gt;&lt;span class=&quot;hl-string hl-quoted hl-double hl-html&quot;&gt;&lt;span class=&quot;hl-meta hl-class-name hl-html&quot;&gt;wiki-category&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-html&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-end hl-html&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-tag hl-inline hl-a hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-begin hl-html&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-inline hl-a hl-html&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;hl-meta hl-attribute-with-value hl-html&quot;&gt;&lt;span class=&quot;hl-entity hl-other hl-attribute-name hl-html&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-html&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-attribute-with-value hl-html&quot;&gt;&lt;span class=&quot;hl-string hl-quoted hl-double hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-html&quot;&gt;&amp;quot;&lt;/span&gt;/wiki/&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-html&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-end hl-html&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Wiki&lt;span class=&quot;hl-meta hl-tag hl-inline hl-a hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-begin hl-html&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-inline hl-a hl-html&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-end hl-html&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;hl-constant hl-character hl-entity hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-entity hl-html&quot;&gt;&amp;amp;&lt;/span&gt;rsaquo&lt;span class=&quot;hl-punctuation hl-definition hl-entity hl-html&quot;&gt;;&lt;/span&gt;&lt;/span&gt; {{ category }}&lt;span class=&quot;hl-meta hl-tag hl-block hl-any hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-begin hl-html&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-block hl-any hl-html&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-end hl-html&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-tag hl-block hl-any hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-begin hl-html&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-block hl-any hl-html&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-end hl-html&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Existing themes that don’t render &lt;code&gt;category&lt;/code&gt; continue to work — you just won’t see it.&lt;/p&gt;
&lt;h3 id=&quot;wiki-categories-name-is-now-a-string-never-null&quot;&gt;&lt;code&gt;wiki_categories[].name&lt;/code&gt; is now a string, never null&lt;/h3&gt;
&lt;p&gt;The wiki sidebar grouping (&lt;code&gt;wiki_categories&lt;/code&gt; on &lt;code&gt;wiki_page.html&lt;/code&gt;, &lt;code&gt;categories&lt;/code&gt; on &lt;code&gt;wiki_index.html&lt;/code&gt;) used to expose &lt;code&gt;name: string?&lt;/code&gt;, requiring templates to fall back to a literal &lt;code&gt;&quot;Other&quot;&lt;/code&gt; for the uncategorised group:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-text hl-html hl-basic&quot;&gt;&lt;span class=&quot;hl-comment hl-block hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-comment hl-begin hl-html&quot;&gt;&amp;lt;!--&lt;/span&gt; Old &lt;span class=&quot;hl-punctuation hl-definition hl-comment hl-end hl-html&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-tag hl-block hl-any hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-begin hl-html&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-block hl-any hl-html&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hl-meta hl-attribute-with-value hl-class hl-html&quot;&gt;&lt;span class=&quot;hl-entity hl-other hl-attribute-name hl-class hl-html&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-html&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-attribute-with-value hl-class hl-html&quot;&gt;&lt;span class=&quot;hl-string hl-quoted hl-double hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-html&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-attribute-with-value hl-class hl-html&quot;&gt;&lt;span class=&quot;hl-string hl-quoted hl-double hl-html&quot;&gt;&lt;span class=&quot;hl-meta hl-class-name hl-html&quot;&gt;wiki-cat-name&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-html&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-end hl-html&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;{% if category.name %}{{ category.name }}{% else %}Other{% endif %}&lt;span class=&quot;hl-meta hl-tag hl-block hl-any hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-begin hl-html&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-block hl-any hl-html&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-end hl-html&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The default is now applied at the renderer using the new &lt;code&gt;wiki_default_category&lt;/code&gt; config field. &lt;code&gt;name&lt;/code&gt; is always populated, so the conditional collapses:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-text hl-html hl-basic&quot;&gt;&lt;span class=&quot;hl-comment hl-block hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-comment hl-begin hl-html&quot;&gt;&amp;lt;!--&lt;/span&gt; New &lt;span class=&quot;hl-punctuation hl-definition hl-comment hl-end hl-html&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-tag hl-block hl-any hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-begin hl-html&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-block hl-any hl-html&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;hl-meta hl-attribute-with-value hl-class hl-html&quot;&gt;&lt;span class=&quot;hl-entity hl-other hl-attribute-name hl-class hl-html&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-html&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-attribute-with-value hl-class hl-html&quot;&gt;&lt;span class=&quot;hl-string hl-quoted hl-double hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-html&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-attribute-with-value hl-class hl-html&quot;&gt;&lt;span class=&quot;hl-string hl-quoted hl-double hl-html&quot;&gt;&lt;span class=&quot;hl-meta hl-class-name hl-html&quot;&gt;wiki-cat-name&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-html&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-end hl-html&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;{{ category.name }}&lt;span class=&quot;hl-meta hl-tag hl-block hl-any hl-html&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-begin hl-html&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-block hl-any hl-html&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-tag hl-end hl-html&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The old form still works (the &lt;code&gt;{% if %}&lt;/code&gt; is just always-true), but you can simplify when convenient.&lt;/p&gt;
&lt;h3 id=&quot;backlinks-removed-from-blog-post-html&quot;&gt;&lt;code&gt;backlinks&lt;/code&gt; removed from &lt;code&gt;blog_post.html&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The v1 scope spec said &lt;em&gt;“Backlinks on wiki pages”&lt;/em&gt; — singular. The implementation drifted into populating &lt;code&gt;backlinks&lt;/code&gt; on every per-page context, including blog posts. That’s now reverted: &lt;code&gt;backlinks&lt;/code&gt; is a &lt;code&gt;wiki_page.html&lt;/code&gt;-only variable.&lt;/p&gt;
&lt;p&gt;If your blog template renders a backlinks section, drop it. If you don’t, the variable simply isn’t there to use.&lt;/p&gt;
&lt;h3 id=&quot;tags-removed-from-wiki-page-html&quot;&gt;&lt;code&gt;tags&lt;/code&gt; removed from &lt;code&gt;wiki_page.html&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Wiki frontmatter still accepts &lt;code&gt;tags&lt;/code&gt;, and tagged wiki pages still appear on tag listings. But the &lt;code&gt;tags&lt;/code&gt; variable is no longer exposed on the wiki page template itself — neither bundled theme rendered it. If you were using it on a custom wiki page, switch to displaying tags on the tag-listing pages instead, or open an issue and we’ll talk about restoring it.&lt;/p&gt;
&lt;h3 id=&quot;wiki-categories-removed-from-blog-post-html-and-page-html&quot;&gt;&lt;code&gt;wiki_categories&lt;/code&gt; removed from &lt;code&gt;blog_post.html&lt;/code&gt; and &lt;code&gt;page.html&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The full sidebar grouping was previously exposed on every per-page context but only ever used by &lt;code&gt;wiki_page.html&lt;/code&gt;. It’s now only on wiki pages, where it makes sense.&lt;/p&gt;
&lt;h3 id=&quot;kind-removed-from-per-page-contexts&quot;&gt;&lt;code&gt;kind&lt;/code&gt; removed from per-page contexts&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;kind&lt;/code&gt; variable (&lt;code&gt;&quot;blog&quot;&lt;/code&gt; / &lt;code&gt;&quot;wiki&quot;&lt;/code&gt; / &lt;code&gt;&quot;page&quot;&lt;/code&gt;) was redundant — each template &lt;em&gt;is&lt;/em&gt; its kind, so no template branched on it. Gone. If yours did, replace with separate templates per kind.&lt;/p&gt;
&lt;h3 id=&quot;universal-core-title-url-content-toc-contains-mermaid&quot;&gt;Universal core: &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;url&lt;/code&gt;, &lt;code&gt;content&lt;/code&gt;, &lt;code&gt;toc&lt;/code&gt;, &lt;code&gt;contains_mermaid&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;These five plus the shared site fields (&lt;code&gt;site_title&lt;/code&gt;, &lt;code&gt;nav_pages&lt;/code&gt;, &lt;code&gt;socials&lt;/code&gt;, &lt;code&gt;favicon_tags&lt;/code&gt;, &lt;code&gt;feed_atom_url&lt;/code&gt;, &lt;code&gt;feed_rss_url&lt;/code&gt;, &lt;code&gt;base_url&lt;/code&gt;, &lt;code&gt;version&lt;/code&gt;) are present on every page template. Previously &lt;code&gt;toc&lt;/code&gt; was wiki+blog only; it’s now also available on &lt;code&gt;page.html&lt;/code&gt; so themes can render a table of contents for standalone pages too.&lt;/p&gt;
&lt;p&gt;The full per-template variable reference is in &lt;a href=&quot;https://aphid.lhelge.se/wiki/themes/&quot;&quot; class=&quot;wikilink&quot;&gt;Themes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;frontmatter-changes&quot;&gt;Frontmatter changes&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;wiki&lt;/code&gt; frontmatter’s &lt;code&gt;title&lt;/code&gt; field accepts the same YAML it always has — omit it and the page derives its title from the filename stem.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;wiki&lt;/code&gt; frontmatter’s &lt;code&gt;category&lt;/code&gt; is also unchanged in YAML (still optional). What changed is what the renderer does when it’s omitted: instead of leaving the value empty for templates to handle, the renderer substitutes &lt;code&gt;wiki_default_category&lt;/code&gt; (default &lt;code&gt;&quot;Other&quot;&lt;/code&gt;), so themes can rely on &lt;code&gt;category&lt;/code&gt; always being a real string.&lt;/p&gt;
&lt;h2 id=&quot;new-config-field&quot;&gt;New config field&lt;/h2&gt;&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-toml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;wiki_default_category&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;Other&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;  &lt;span class=&quot;hl-comment hl-line hl-number-sign hl-toml&quot;&gt;# default&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sets the display name for wiki pages without an explicit &lt;code&gt;category&lt;/code&gt;. Surfaces both as the page’s own &lt;code&gt;category&lt;/code&gt; value and as the heading of the catch-all group on the wiki index. Set this if you’d prefer “Misc” or “Uncategorised” or your own term.&lt;/p&gt;
&lt;h2 id=&quot;dev-server-quality-of-life&quot;&gt;Dev-server quality of life&lt;/h2&gt;
&lt;p&gt;Two small wins for &lt;code&gt;aphid serve&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Favicon edits hot-reload.&lt;/strong&gt; Saving a new &lt;code&gt;favicon.png&lt;/code&gt; while the server is running now triggers a rebuild that detects the change and re-encodes the icon set. Editing markdown stays as fast as ever — the favicon is only re-encoded when its source actually changed. (Previously, favicon source changes were ignored until you restarted the server.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Config edits trigger rebuilds.&lt;/strong&gt; &lt;code&gt;aphid.toml&lt;/code&gt; is now watched alongside the content directories, so editing the title, swapping the favicon path, changing &lt;code&gt;posts_per_page&lt;/code&gt; or &lt;code&gt;wiki_default_category&lt;/code&gt; all trigger a rebuild without a restart. The exception is &lt;code&gt;source_dir&lt;/code&gt; / &lt;code&gt;static_dir&lt;/code&gt; / &lt;code&gt;theme_dir&lt;/code&gt; — changing those still needs a restart, because those are the directories the watcher itself is registered on.&lt;/p&gt;
&lt;h2 id=&quot;author-profile-images&quot;&gt;Author profile images&lt;/h2&gt;
&lt;p&gt;Authors configured in &lt;code&gt;aphid.toml&lt;/code&gt; now support an optional &lt;code&gt;image&lt;/code&gt; field:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-table hl-array hl-begin hl-toml&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;hl-entity hl-name hl-section hl-toml&quot;&gt;authors&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-table hl-array hl-end hl-toml&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;Alice&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;email&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;alice@example.com&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;image&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-double hl-toml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;authors/alice.jpg&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-toml&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The image path is relative to your &lt;code&gt;static/&lt;/code&gt; directory (served at &lt;code&gt;/static/&lt;/code&gt;); absolute URLs (&lt;code&gt;https://…&lt;/code&gt;) also work.&lt;/p&gt;
&lt;p&gt;In blog post templates, &lt;code&gt;author&lt;/code&gt; is now a struct with &lt;code&gt;.name&lt;/code&gt;, &lt;code&gt;.email&lt;/code&gt;, and &lt;code&gt;.image&lt;/code&gt; instead of a plain string. The bundled themes render a round profile picture next to the author name — when no image is configured, a gray silhouette SVG is shown as a fallback. If the author has an email, the avatar and name are wrapped in a &lt;code&gt;mailto:&lt;/code&gt; link.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Breaking:&lt;/strong&gt; templates that used &lt;code&gt;{{ author }}&lt;/code&gt; must update to &lt;code&gt;{{ author.name }}&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;upgrading&quot;&gt;Upgrading&lt;/h2&gt;&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-shell hl-bash&quot;&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;cargo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; install aphid&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;locked&lt;/span&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;force&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;version&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you use only the bundled themes, that’s it. If you have a custom theme, walk through the &lt;strong&gt;Theme changes&lt;/strong&gt; section above.&lt;/p&gt;
</content>
    <category term="aphid"/>
    <category term="release"/>
    <category term="breaking"/>
    <category term="themes"/>
  </entry>
  <entry>
    <title>aphid 0.1.4</title>
    <link href="https://aphid.lhelge.se/blog/v0-1-4/" rel="alternate" type="text/html"/>
    <id>https://aphid.lhelge.se/blog/v0-1-4/</id>
    <published>2026-05-06T00:00:00+00:00</published>
    <updated>2026-05-06T00:00:00+00:00</updated>
    <author>
      <name>LHelge</name>
    </author>
    <summary type="text">A quality-of-life release fixing feed links for readers, normalizing image paths in markdown, validating config, improving error messages, and adding a reusable GitHub Action for CI builds.</summary>
    <content type="html">&lt;p&gt;aphid 0.1.4 is a polish release. No new features — just fixes for things that tripped people up in practice: broken links in feed readers, images that only worked on the home page, and error messages that didn’t explain what went wrong.&lt;/p&gt;
&lt;h2 id=&quot;absolute-urls-in-feeds&quot;&gt;Absolute URLs in feeds&lt;/h2&gt;
&lt;p&gt;Feed readers fetch content outside the context of your site’s domain, so relative links like &lt;code&gt;/blog/other-post/&lt;/code&gt; are meaningless to them. Both the Atom and RSS feeds now rewrite all &lt;code&gt;href&lt;/code&gt; and &lt;code&gt;src&lt;/code&gt; attributes in post content to full URLs using &lt;code&gt;base_url&lt;/code&gt; from your config. The feed metadata links (self-link, entry permalinks) were already absolute — this fixes the inline content body.&lt;/p&gt;
&lt;p&gt;Before: &lt;code&gt;&amp;lt;a href=&quot;https://aphid.lhelge.se/wiki/configuration/&quot;&quot;&amp;gt;&lt;/code&gt; inside &lt;code&gt;&amp;lt;content type=&quot;html&quot;&amp;gt;&lt;/code&gt;
After: &lt;code&gt;&amp;lt;a href=&quot;https://your-site.com/wiki/configuration/&quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;No configuration needed — it uses the &lt;code&gt;base_url&lt;/code&gt; you already have.&lt;/p&gt;
&lt;h2 id=&quot;relative-image-path-normalization&quot;&gt;Relative image path normalization&lt;/h2&gt;
&lt;p&gt;Writing &lt;code&gt;![screenshot](static/blog/screenshot.png)&lt;/code&gt; (without the leading &lt;code&gt;/&lt;/code&gt;) worked on the home page but broke on blog posts and the blog index, because the browser resolved it relative to the current URL path. The markdown pipeline now detects bare relative paths and normalizes them to root-relative (&lt;code&gt;/static/blog/screenshot.png&lt;/code&gt;) during rendering. This applies to both links and images, but leaves fragments (&lt;code&gt;#heading&lt;/code&gt;), absolute URLs, and &lt;code&gt;mailto:&lt;/code&gt; links untouched.&lt;/p&gt;
&lt;h2 id=&quot;config-validation&quot;&gt;Config validation&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;base_url&lt;/code&gt; must now start with &lt;code&gt;http://&lt;/code&gt; or &lt;code&gt;https://&lt;/code&gt;. Previously, setting &lt;code&gt;base_url = &quot;/&quot;&lt;/code&gt; (common when testing locally without a domain) silently produced empty-string URLs in feeds and the sitemap after trailing-slash normalization. aphid now fails fast at config load time with a clear message:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-text hl-plain&quot;&gt;Error: invalid config: base_url: must start with http:// or https://, got &amp;quot;/&amp;quot;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;better-error-for-non-utf-8-files&quot;&gt;Better error for non-UTF-8 files&lt;/h2&gt;
&lt;p&gt;If a &lt;code&gt;.md&lt;/code&gt; file contains invalid UTF-8 bytes (wrong encoding, binary accidentally renamed), the error previously surfaced as a generic I/O failure. It now says exactly what’s wrong:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-text hl-plain&quot;&gt;Error: content/wiki/notes.md is not valid UTF-8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;github-action&quot;&gt;GitHub Action&lt;/h2&gt;
&lt;p&gt;A reusable composite action is now available for CI deployments. Instead of installing Rust and building from source, reference the action to download a pre-built binary:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-yaml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-block hl-sequence hl-item hl-yaml&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-yaml&quot;&gt;uses&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-mapping hl-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;actions/checkout@v4&lt;/span&gt;

&lt;span class=&quot;hl-punctuation hl-definition hl-block hl-sequence hl-item hl-yaml&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-yaml&quot;&gt;uses&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-mapping hl-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;LHelge/aphid@main&lt;/span&gt;
  &lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-yaml&quot;&gt;with&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-mapping hl-yaml&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-yaml&quot;&gt;version&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-mapping hl-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-single hl-yaml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-yaml&quot;&gt;&amp;#39;&lt;/span&gt;v0.1.4&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-yaml&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;  &lt;span class=&quot;hl-comment hl-line hl-number-sign hl-yaml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-comment hl-line hl-number-sign hl-yaml&quot;&gt;#&lt;/span&gt; optional, defaults to latest
&lt;/span&gt;    &lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-yaml&quot;&gt;output&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-mapping hl-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-string hl-quoted hl-single hl-yaml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-yaml&quot;&gt;&amp;#39;&lt;/span&gt;_site&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-yaml&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;     &lt;span class=&quot;hl-comment hl-line hl-number-sign hl-yaml&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-comment hl-line hl-number-sign hl-yaml&quot;&gt;#&lt;/span&gt; optional, defaults to dist
&lt;/span&gt;
&lt;span class=&quot;hl-punctuation hl-definition hl-block hl-sequence hl-item hl-yaml&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-yaml&quot;&gt;uses&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-mapping hl-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;actions/upload-pages-artifact@v5&lt;/span&gt;
  &lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-yaml&quot;&gt;with&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-mapping hl-yaml&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-yaml&quot;&gt;path&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-mapping hl-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;_site&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It detects the runner platform automatically and supports Linux (x64, arm64), macOS (arm64), and Windows (x64). See &lt;a href=&quot;https://aphid.lhelge.se/wiki/deployment/&quot;&quot; class=&quot;wikilink&quot;&gt;Deployment&lt;/a&gt; for a complete Pages workflow example.&lt;/p&gt;
&lt;h2 id=&quot;upgrading&quot;&gt;Upgrading&lt;/h2&gt;&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-shell hl-bash&quot;&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;cargo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; install aphid&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;locked&lt;/span&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;force&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;version&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are no breaking changes from 0.1.3 unless your &lt;code&gt;base_url&lt;/code&gt; was already invalid (not starting with &lt;code&gt;http://&lt;/code&gt; or &lt;code&gt;https://&lt;/code&gt;). If so, fix it in &lt;code&gt;aphid.toml&lt;/code&gt; — the config error will tell you exactly what’s expected.&lt;/p&gt;
</content>
    <category term="aphid"/>
    <category term="release"/>
    <category term="deployment"/>
  </entry>
  <entry>
    <title>aphid 0.1.3</title>
    <link href="https://aphid.lhelge.se/blog/v0-1-3/" rel="alternate" type="text/html"/>
    <id>https://aphid.lhelge.se/blog/v0-1-3/</id>
    <published>2026-05-02T00:00:00+00:00</published>
    <updated>2026-05-02T00:00:00+00:00</updated>
    <author>
      <name>LHelge</name>
    </author>
    <summary type="text">A scaffolding release adding `aphid new`, `aphid init`, and content creation commands for blog posts, wiki pages, and standalone pages.</summary>
    <content type="html">&lt;p&gt;aphid 0.1.3 is about getting started faster. Instead of creating directories and files by hand, a single command now scaffolds a complete site or adds a new content file with the right frontmatter already in place.&lt;/p&gt;
&lt;h2 id=&quot;site-scaffolding&quot;&gt;Site scaffolding&lt;/h2&gt;
&lt;p&gt;Two new commands set up a fresh aphid site from scratch:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-shell hl-bash&quot;&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; new my-blog     &lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-comment hl-begin hl-shell&quot;&gt;#&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt; create my-blog/ with everything inside&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; init            &lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-comment hl-begin hl-shell&quot;&gt;#&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt; scaffold in the current directory&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; init path/to    &lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-comment hl-begin hl-shell&quot;&gt;#&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt; scaffold in a specific directory&lt;/span&gt;&lt;span class=&quot;hl-comment hl-line hl-number-sign hl-shell&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both generate a minimal but buildable site: &lt;code&gt;aphid.toml&lt;/code&gt; with a title derived from the directory name, a &lt;code&gt;.gitignore&lt;/code&gt; for &lt;code&gt;/dist&lt;/code&gt;, a starter blog post, a “Getting Started” wiki page, an about page, a home page, and an empty &lt;code&gt;static/&lt;/code&gt; directory. The site is built immediately after scaffolding, so &lt;code&gt;dist/&lt;/code&gt; is ready to serve:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-shell hl-bash&quot;&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; new my-blog&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-support hl-function hl-cd hl-shell&quot;&gt;cd&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; my-blog&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; serve&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;aphid new&lt;/code&gt; fails if the target directory already exists; &lt;code&gt;aphid init&lt;/code&gt; fails if the directory already contains an &lt;code&gt;aphid.toml&lt;/code&gt;. Both are intentional guard rails — no silent overwrites.&lt;/p&gt;
&lt;h2 id=&quot;content-creation&quot;&gt;Content creation&lt;/h2&gt;
&lt;p&gt;Once a site exists, three commands create new content files with valid frontmatter:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-shell hl-bash&quot;&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; blog new &lt;span class=&quot;hl-string hl-quoted hl-double hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-shell&quot;&gt;&amp;quot;&lt;/span&gt;My First Post&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-shell&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; wiki new &lt;span class=&quot;hl-string hl-quoted hl-double hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-shell&quot;&gt;&amp;quot;&lt;/span&gt;Architecture Overview&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-shell&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; page new &lt;span class=&quot;hl-string hl-quoted hl-double hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-begin hl-shell&quot;&gt;&amp;quot;&lt;/span&gt;Contact&lt;span class=&quot;hl-punctuation hl-definition hl-string hl-end hl-shell&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each derives the filename slug from the title (&lt;code&gt;&quot;My First Post&quot;&lt;/code&gt; → &lt;code&gt;my-first-post&lt;/code&gt;). Blog posts are prefixed with today’s date and get the full blog frontmatter (&lt;code&gt;title&lt;/code&gt;, &lt;code&gt;slug&lt;/code&gt;, &lt;code&gt;author&lt;/code&gt;, &lt;code&gt;created&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, &lt;code&gt;tags&lt;/code&gt;). Wiki and standalone pages get lighter frontmatter matching their respective types. All three commands check for an existing &lt;code&gt;aphid.toml&lt;/code&gt; via the &lt;code&gt;--config&lt;/code&gt; flag and write into the configured &lt;code&gt;source_dir&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If a file with the same slug already exists the command fails rather than overwriting — rename or delete the existing file first.&lt;/p&gt;
&lt;h2 id=&quot;upgrading&quot;&gt;Upgrading&lt;/h2&gt;&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-shell hl-bash&quot;&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;cargo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; install aphid&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;locked&lt;/span&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;force&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;version&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are no breaking changes from 0.1.2. The new commands are purely additive — existing sites and workflows are unaffected.&lt;/p&gt;
</content>
    <category term="aphid"/>
    <category term="release"/>
    <category term="cli"/>
  </entry>
  <entry>
    <title>aphid 0.1.2</title>
    <link href="https://aphid.lhelge.se/blog/v0-1-2/" rel="alternate" type="text/html"/>
    <id>https://aphid.lhelge.se/blog/v0-1-2/</id>
    <published>2026-05-01T00:00:00+00:00</published>
    <updated>2026-05-01T00:00:00+00:00</updated>
    <author>
      <name>LHelge</name>
    </author>
    <summary type="text">A content-flow release adding RSS/Atom feeds, pagination for the blog index and tag pages, and a draft flag for unpublished work.</summary>
    <content type="html">&lt;p&gt;aphid 0.1.2 is a release about everyday writing flow: keeping readers up to date with feeds, keeping listings readable as the archive grows, and keeping half-finished pieces out of the published site until they’re ready.&lt;/p&gt;
&lt;h2 id=&quot;rss-and-atom-feeds&quot;&gt;RSS and Atom feeds&lt;/h2&gt;
&lt;p&gt;Every build now emits an Atom feed at &lt;code&gt;/feed.xml&lt;/code&gt; and an RSS feed at &lt;code&gt;/rss.xml&lt;/code&gt;, both linked from every page’s &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; so feed readers can discover them automatically. The feed picks up the newest blog posts, and a new &lt;code&gt;feed_limit&lt;/code&gt; setting in &lt;code&gt;aphid.toml&lt;/code&gt; controls how many appear:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-toml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;feed_limit&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-constant hl-numeric hl-integer hl-decimal hl-toml&quot;&gt;20&lt;/span&gt;   &lt;span class=&quot;hl-comment hl-line hl-number-sign hl-toml&quot;&gt;# default; set to 0 for no limit&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both feeds are generated only in &lt;code&gt;aphid build&lt;/code&gt; — &lt;code&gt;aphid serve&lt;/code&gt; skips them so dev rebuilds stay fast. See &lt;a href=&quot;https://aphid.lhelge.se/wiki/configuration/&quot;&quot; class=&quot;wikilink&quot;&gt;Configuration&lt;/a&gt; for the full field list.&lt;/p&gt;
&lt;h2 id=&quot;pagination&quot;&gt;Pagination&lt;/h2&gt;
&lt;p&gt;The blog index and per-tag pages now split into pages of &lt;code&gt;posts_per_page&lt;/code&gt; once the listing grows past that count. Page 1 stays at the canonical URL (&lt;code&gt;/blog/&lt;/code&gt;, &lt;code&gt;/tags/rust/&lt;/code&gt;); subsequent pages live at &lt;code&gt;/blog/page/2/&lt;/code&gt;, &lt;code&gt;/tags/rust/page/2/&lt;/code&gt;, and so on:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-toml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-toml&quot;&gt;posts_per_page&lt;/span&gt; &lt;span class=&quot;hl-keyword hl-operator hl-assignment hl-toml&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-constant hl-numeric hl-integer hl-decimal hl-toml&quot;&gt;10&lt;/span&gt;   &lt;span class=&quot;hl-comment hl-line hl-number-sign hl-toml&quot;&gt;# default&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The full mechanics — URL scheme, the &lt;code&gt;pagination&lt;/code&gt; template variable, and the page-1-only treatment for “featured” cards — are in &lt;a href=&quot;https://aphid.lhelge.se/wiki/pagination/&quot;&quot; class=&quot;wikilink&quot;&gt;Pagination&lt;/a&gt;. Themes get a &lt;code&gt;pagination.html&lt;/code&gt; partial that renders prev/next/numeric nav, and the docs theme uses &lt;code&gt;pagination.current == 1&lt;/code&gt; to gate its featured-post layout so page 2 onwards renders every post in the same compact format.&lt;/p&gt;
&lt;h2 id=&quot;drafts&quot;&gt;Drafts&lt;/h2&gt;
&lt;p&gt;Setting &lt;code&gt;draft: true&lt;/code&gt; in any content file’s frontmatter excludes it from the build entirely:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-yaml&quot;&gt;&lt;span class=&quot;hl-entity hl-other hl-document hl-begin hl-yaml&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-yaml&quot;&gt;title&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-mapping hl-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;Half-finished thoughts&lt;/span&gt;
&lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-yaml&quot;&gt;slug&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-mapping hl-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;wip&lt;/span&gt;
&lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-yaml&quot;&gt;author&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-mapping hl-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;LHelge&lt;/span&gt;
&lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-yaml&quot;&gt;created&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-mapping hl-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-constant hl-other hl-timestamp hl-yaml&quot;&gt;2026-05-01&lt;/span&gt;
&lt;span class=&quot;hl-string hl-unquoted hl-plain hl-out hl-yaml&quot;&gt;&lt;span class=&quot;hl-entity hl-name hl-tag hl-yaml&quot;&gt;draft&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-punctuation hl-separator hl-key-value hl-mapping hl-yaml&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-constant hl-language hl-boolean hl-yaml&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;hl-entity hl-other hl-document hl-begin hl-yaml&quot;&gt;---&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A draft has no rendered page, no entry in any listing, no presence in the feeds or sitemap, and no nav entry (for standalone pages). Wiki-links pointing at a draft fail to resolve as if the file did not exist on disk — &lt;code&gt;aphid build&lt;/code&gt; reports a broken link error and &lt;code&gt;aphid serve&lt;/code&gt; warns. There is no preview override; to publish, change the flag to &lt;code&gt;false&lt;/code&gt; or remove it. See &lt;a href=&quot;https://aphid.lhelge.se/wiki/frontmatter/&quot;&quot; class=&quot;wikilink&quot;&gt;Frontmatter&lt;/a&gt; for the field’s full semantics.&lt;/p&gt;
&lt;h2 id=&quot;also-in-0-1-2&quot;&gt;Also in 0.1.2&lt;/h2&gt;
&lt;p&gt;A handful of smaller things landed alongside the headline features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Adjacent post nav.&lt;/strong&gt; Every blog post now shows the previous (newer) and next (older) post at the bottom, with date and title. The values are exposed to templates as &lt;code&gt;newer_post&lt;/code&gt; and &lt;code&gt;older_post&lt;/code&gt; on the blog post context.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tag-aware cards.&lt;/strong&gt; Tag badges on the blog index and home-page cards link to the tag page, not the post — clicking the rest of the card still opens the post.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tag pages share the blog-index layout.&lt;/strong&gt; The docs theme used to show tag pages as a thin list; they now use the same compact-card format as the blog index, minus the featured treatment.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;upgrading&quot;&gt;Upgrading&lt;/h2&gt;&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-shell hl-bash&quot;&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;cargo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; install aphid&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;locked&lt;/span&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;force&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;version&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are no breaking changes from 0.1.1. Existing &lt;code&gt;aphid.toml&lt;/code&gt; files keep working — &lt;code&gt;feed_limit&lt;/code&gt; and &lt;code&gt;posts_per_page&lt;/code&gt; both default sensibly, and &lt;code&gt;draft&lt;/code&gt; is opt-in per file.&lt;/p&gt;
</content>
    <category term="aphid"/>
    <category term="release"/>
    <category term="content"/>
  </entry>
  <entry>
    <title>aphid 0.1.1</title>
    <link href="https://aphid.lhelge.se/blog/v0-1-1/" rel="alternate" type="text/html"/>
    <id>https://aphid.lhelge.se/blog/v0-1-1/</id>
    <published>2026-04-30T00:00:00+00:00</published>
    <updated>2026-04-30T00:00:00+00:00</updated>
    <author>
      <name>LHelge</name>
    </author>
    <summary type="text">A small content-focused release adding Mermaid diagrams, GitHub-style alert blocks, and smart punctuation to the markdown pipeline.</summary>
    <content type="html">&lt;p&gt;aphid 0.1.1 is a small follow-up to &lt;a href=&quot;https://aphid.lhelge.se/blog/v0-1/&quot;&quot; class=&quot;wikilink&quot;&gt;aphid 0.1.0&lt;/a&gt;, focused on the markdown pipeline. The headline adds are &lt;strong&gt;Mermaid diagrams&lt;/strong&gt; rendered client-side and &lt;strong&gt;GitHub-style alert blocks&lt;/strong&gt;. Both are things I wanted while writing the docs you’re reading.&lt;/p&gt;
&lt;h2 id=&quot;mermaid-diagrams&quot;&gt;Mermaid diagrams&lt;/h2&gt;
&lt;p&gt;Fenced blocks tagged &lt;code&gt;mermaid&lt;/code&gt; are now rendered as live diagrams in the browser. Source goes in, SVG comes out:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-text hl-html hl-markdown&quot;&gt;&lt;span class=&quot;hl-meta hl-paragraph hl-markdown&quot;&gt;&lt;span class=&quot;hl-markup hl-raw hl-code-fence hl-markdown&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-raw hl-code-fence hl-begin hl-markdown&quot;&gt;```&lt;/span&gt;&lt;span class=&quot;hl-constant hl-other hl-language-name hl-markdown&quot;&gt;mermaid&lt;/span&gt;
sequenceDiagram
    Browser-&amp;gt;&amp;gt;aphid: GET /wiki/markdown/
    aphid-&amp;gt;&amp;gt;Browser: HTML + &amp;lt;pre class=&amp;quot;mermaid&amp;quot;&amp;gt;
    Browser-&amp;gt;&amp;gt;Mermaid: parse .mermaid blocks
    Mermaid--&amp;gt;&amp;gt;Browser: SVG diagrams
&lt;span class=&quot;hl-punctuation hl-definition hl-raw hl-code-fence hl-end hl-markdown&quot;&gt;```
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Renders as:&lt;/p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;sequenceDiagram
    Browser-&amp;gt;&amp;gt;aphid: GET /wiki/markdown/
    aphid-&amp;gt;&amp;gt;Browser: HTML + &amp;lt;pre class=&amp;quot;mermaid&amp;quot;&amp;gt;
    Browser-&amp;gt;&amp;gt;Mermaid: parse .mermaid blocks
    Mermaid--&amp;gt;&amp;gt;Browser: SVG diagrams
&lt;/pre&gt;
&lt;p&gt;A few notes on how it’s wired:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Mermaid runtime is &lt;strong&gt;vendored with aphid&lt;/strong&gt; — no CDN, no third-party request at page load. The bundle ships inside the binary and is written out next to the rest of the theme’s static files.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; only loads on pages that actually contain a mermaid block. Index pages, posts without diagrams, and the 404 page all stay clean.&lt;/li&gt;
&lt;li&gt;The build pipeline emits each block as &lt;code&gt;&amp;lt;pre class=&quot;mermaid&quot;&amp;gt;…source…&amp;lt;/pre&amp;gt;&lt;/code&gt;, so if JavaScript is disabled the reader still sees the original diagram source rather than a blank space.&lt;/li&gt;
&lt;li&gt;Flowcharts, sequence diagrams, class diagrams, state diagrams, gantt charts, ER diagrams, mindmaps, gitgraphs — anything Mermaid supports works. See &lt;a href=&quot;https://aphid.lhelge.se/wiki/mermaid/&quot;&quot; class=&quot;wikilink&quot;&gt;Mermaid diagrams&lt;/a&gt; for a tour of the common diagram types with worked examples, or &lt;a href=&quot;https://aphid.lhelge.se/wiki/markdown/&quot;&quot; class=&quot;wikilink&quot;&gt;Markdown&lt;/a&gt; for the pipeline detail.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;markdown-alerts&quot;&gt;Markdown alerts&lt;/h2&gt;
&lt;p&gt;The five GitHub-flavoured alert types are recognised at parse time:&lt;/p&gt;
&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-text hl-html hl-markdown&quot;&gt;&lt;span class=&quot;hl-meta hl-block-level hl-markdown&quot;&gt;&lt;span class=&quot;hl-markup hl-quote hl-markdown&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-blockquote hl-markdown&quot;&gt;&amp;gt;&lt;/span&gt; [!NOTE]
&lt;/span&gt;&lt;span class=&quot;hl-markup hl-quote hl-markdown&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-blockquote hl-markdown&quot;&gt;&amp;gt;&lt;/span&gt; Highlights information that users should take into account, even when skimming.
&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-block-level hl-markdown&quot;&gt;&lt;span class=&quot;hl-markup hl-quote hl-markdown&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-blockquote hl-markdown&quot;&gt;&amp;gt;&lt;/span&gt; [!TIP]
&lt;/span&gt;&lt;span class=&quot;hl-markup hl-quote hl-markdown&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-blockquote hl-markdown&quot;&gt;&amp;gt;&lt;/span&gt; Optional information to help a user be more successful.
&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-block-level hl-markdown&quot;&gt;&lt;span class=&quot;hl-markup hl-quote hl-markdown&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-blockquote hl-markdown&quot;&gt;&amp;gt;&lt;/span&gt; [!IMPORTANT]
&lt;/span&gt;&lt;span class=&quot;hl-markup hl-quote hl-markdown&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-blockquote hl-markdown&quot;&gt;&amp;gt;&lt;/span&gt; Crucial information necessary for users to succeed.
&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-block-level hl-markdown&quot;&gt;&lt;span class=&quot;hl-markup hl-quote hl-markdown&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-blockquote hl-markdown&quot;&gt;&amp;gt;&lt;/span&gt; [!WARNING]
&lt;/span&gt;&lt;span class=&quot;hl-markup hl-quote hl-markdown&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-blockquote hl-markdown&quot;&gt;&amp;gt;&lt;/span&gt; Critical content demanding immediate user attention due to potential risks.
&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-block-level hl-markdown&quot;&gt;&lt;span class=&quot;hl-markup hl-quote hl-markdown&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-blockquote hl-markdown&quot;&gt;&amp;gt;&lt;/span&gt; [!CAUTION]
&lt;/span&gt;&lt;span class=&quot;hl-markup hl-quote hl-markdown&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-blockquote hl-markdown&quot;&gt;&amp;gt;&lt;/span&gt; Negative potential consequences of an action.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rendered:&lt;/p&gt;
&lt;div class=&quot;markdown-alert markdown-alert-note&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;Highlights information that users should take into account, even when skimming.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;markdown-alert markdown-alert-tip&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Tip&lt;/p&gt;
&lt;p&gt;Optional information to help a user be more successful.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;markdown-alert markdown-alert-important&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Important&lt;/p&gt;
&lt;p&gt;Crucial information necessary for users to succeed.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;markdown-alert markdown-alert-warning&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Warning&lt;/p&gt;
&lt;p&gt;Critical content demanding immediate user attention due to potential risks.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;markdown-alert markdown-alert-caution&quot;&gt;
&lt;p class=&quot;markdown-alert-title&quot;&gt;Caution&lt;/p&gt;
&lt;p&gt;Negative potential consequences of an action.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Each alert is emitted as &lt;code&gt;&amp;lt;div class=&quot;markdown-alert markdown-alert-{type}&quot;&amp;gt;&lt;/code&gt;, so themes can style the five types independently. Plain blockquotes (&lt;code&gt;&amp;gt;&lt;/code&gt; without a &lt;code&gt;[!TYPE]&lt;/code&gt; marker) are untouched — there’s no behavioural change to existing content.&lt;/p&gt;
&lt;h2 id=&quot;also-in-0-1-1&quot;&gt;Also in 0.1.1&lt;/h2&gt;
&lt;p&gt;A handful of smaller things landed alongside the two headline features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Smart punctuation.&lt;/strong&gt; Straight quotes are converted to curly quotes, &lt;code&gt;--&lt;/code&gt; to en-dashes, &lt;code&gt;---&lt;/code&gt; to em-dashes, and &lt;code&gt;...&lt;/code&gt; to ellipses, all at parse time. Just write natural prose.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Favicon generation.&lt;/strong&gt; Point &lt;code&gt;favicon&lt;/code&gt; in &lt;code&gt;aphid.toml&lt;/code&gt; at a single source image and aphid emits the full set of platform icons plus the matching &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; tags injected into every page’s &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;. See &lt;a href=&quot;https://aphid.lhelge.se/wiki/configuration/&quot;&quot; class=&quot;wikilink&quot;&gt;Configuration&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;robots.txt&lt;/code&gt; and &lt;code&gt;sitemap.xml&lt;/code&gt;.&lt;/strong&gt; Both are generated automatically at the site root.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;upgrading&quot;&gt;Upgrading&lt;/h2&gt;&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-shell hl-bash&quot;&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;cargo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; install aphid&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;locked&lt;/span&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;force&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;version&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are no breaking changes from 0.1.0 — alerts, mermaid, and smart punctuation are all additive at the markdown layer, and existing content renders identically unless it contained a literal &lt;code&gt;```mermaid&lt;/code&gt; block, a &lt;code&gt;&amp;gt; [!TYPE]&lt;/code&gt; blockquote, or relied on raw &lt;code&gt;--&lt;/code&gt; / &lt;code&gt;...&lt;/code&gt; in prose.&lt;/p&gt;
</content>
    <category term="aphid"/>
    <category term="release"/>
    <category term="markdown"/>
  </entry>
  <entry>
    <title>aphid 0.1.0</title>
    <link href="https://aphid.lhelge.se/blog/v0-1/" rel="alternate" type="text/html"/>
    <id>https://aphid.lhelge.se/blog/v0-1/</id>
    <published>2026-04-28T00:00:00+00:00</published>
    <updated>2026-04-28T00:00:00+00:00</updated>
    <author>
      <name>LHelge</name>
    </author>
    <summary type="text">The first tagged release of aphid — a static site generator with a blog, a wiki, and wiki-links across both.</summary>
    <content type="html">&lt;p&gt;aphid 0.1.0 is out. This is the first tagged release — enough is working to build and deploy a real site, which is what you’re reading right now.&lt;/p&gt;
&lt;h2 id=&quot;what-s-in-the-box&quot;&gt;What’s in the box&lt;/h2&gt;
&lt;p&gt;The core feature set, the things that make aphid useful rather than just a toy:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Three content types&lt;/strong&gt; — blog posts, wiki pages, and standalone pages, each with their own frontmatter shape and URL scheme. See &lt;a href=&quot;https://aphid.lhelge.se/wiki/frontmatter/&quot;&quot; class=&quot;wikilink&quot;&gt;Frontmatter&lt;/a&gt; for the details.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wiki-links&lt;/strong&gt; — &lt;code&gt;[[slug]]&lt;/code&gt; and &lt;code&gt;[[slug|Display text]]&lt;/code&gt; resolve across all content types. Broken links fail the build in &lt;code&gt;aphid build&lt;/code&gt; and render visibly in &lt;code&gt;aphid serve&lt;/code&gt;. Full details in &lt;a href=&quot;https://aphid.lhelge.se/wiki/wiki-links/&quot;&quot; class=&quot;wikilink&quot;&gt;Wiki Links&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Two-pass pipeline&lt;/strong&gt; — a first pass indexes every file to build the slug map and backlink graph, then a second pass renders all pages in parallel via rayon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Syntax highlighting&lt;/strong&gt; — fenced code blocks are highlighted with syntect using CSS classes, so colors are controlled entirely by the theme stylesheet. See &lt;a href=&quot;https://aphid.lhelge.se/wiki/markdown/&quot;&quot; class=&quot;wikilink&quot;&gt;Markdown&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auto heading anchors&lt;/strong&gt; — every heading gets a slug-based &lt;code&gt;id&lt;/code&gt; attribute. Duplicate headings on the same page get &lt;code&gt;-2&lt;/code&gt;, &lt;code&gt;-3&lt;/code&gt; suffixes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tag index pages&lt;/strong&gt; — blog posts can be tagged, and aphid generates a page per tag plus a tags index.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Backlinks&lt;/strong&gt; — wiki pages show which other pages link to them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dev server with live reload&lt;/strong&gt; — &lt;code&gt;aphid serve&lt;/code&gt; runs an axum server with file watching and WebSocket-driven browser refresh. See &lt;a href=&quot;https://aphid.lhelge.se/wiki/dev-server/&quot;&quot; class=&quot;wikilink&quot;&gt;Dev server&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Embedded default theme&lt;/strong&gt; — a fresh project needs only &lt;code&gt;aphid.toml&lt;/code&gt; and a &lt;code&gt;content/&lt;/code&gt; directory. The default theme is compiled into the binary. Override it by setting &lt;code&gt;theme_dir&lt;/code&gt;. See &lt;a href=&quot;https://aphid.lhelge.se/wiki/themes/&quot;&quot; class=&quot;wikilink&quot;&gt;Themes&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clean URLs&lt;/strong&gt; — &lt;code&gt;content/wiki/foo.md&lt;/code&gt; is served at &lt;code&gt;/wiki/foo/&lt;/code&gt;, backed by &lt;code&gt;dist/wiki/foo/index.html&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Pages deployment&lt;/strong&gt; — &lt;code&gt;aphid build&lt;/code&gt; produces a self-contained output directory ready for any static host. See &lt;a href=&quot;https://aphid.lhelge.se/wiki/deployment/&quot;&quot; class=&quot;wikilink&quot;&gt;Deployment&lt;/a&gt; for a ready-made GitHub Actions workflow.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;what-s-not-in-0-1-0&quot;&gt;What’s not in 0.1.0&lt;/h2&gt;
&lt;p&gt;Some things are deliberately deferred:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Drafts&lt;/strong&gt; — no &lt;code&gt;draft: true&lt;/code&gt; support yet. Everything in &lt;code&gt;content/&lt;/code&gt; is published.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RSS / Atom feeds&lt;/strong&gt; — planned but not v1.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pagination&lt;/strong&gt; — the blog index and tag pages list all posts on a single page.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Search&lt;/strong&gt; — no client-side search. The wiki is small enough that the index page and cross-links cover navigation for now.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;aphid init&lt;/code&gt;&lt;/strong&gt; — a scaffolding command to set up a clean project, similar to &lt;code&gt;cargo init&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mermaid diagrams&lt;/strong&gt; — render &lt;code&gt;mermaid&lt;/code&gt; fenced code blocks as diagrams.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Math&lt;/strong&gt; — Render TeX strings as math expressions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sitemap generation&lt;/strong&gt; — emit a &lt;code&gt;sitemap.xml&lt;/code&gt; for search engines.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Open Graph / SEO meta tags&lt;/strong&gt; — templates should emit &lt;code&gt;&amp;lt;meta og:*&amp;gt;&lt;/code&gt; tags from existing frontmatter fields like &lt;code&gt;description&lt;/code&gt; and &lt;code&gt;image&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;…and more.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;try-it&quot;&gt;Try it&lt;/h2&gt;&lt;pre class=&quot;code-block&quot;&gt;&lt;code&gt;&lt;span class=&quot;hl-source hl-shell hl-bash&quot;&gt;&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;cargo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt; install aphid&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;locked&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hl-meta hl-function-call hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-function hl-shell&quot;&gt;aphid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hl-meta hl-function-call hl-arguments hl-shell&quot;&gt;&lt;span class=&quot;hl-variable hl-parameter hl-option hl-shell&quot;&gt;&lt;span class=&quot;hl-punctuation hl-definition hl-parameter hl-shell&quot;&gt; --&lt;/span&gt;version&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Create an &lt;code&gt;aphid.toml&lt;/code&gt;, add some markdown files under &lt;code&gt;content/&lt;/code&gt;, and run &lt;code&gt;aphid serve&lt;/code&gt; to see it live. The &lt;a href=&quot;https://aphid.lhelge.se/wiki/installation/&quot;&quot; class=&quot;wikilink&quot;&gt;Installation&lt;/a&gt; and &lt;a href=&quot;https://aphid.lhelge.se/wiki/cli/&quot;&quot; class=&quot;wikilink&quot;&gt;CLI reference&lt;/a&gt; pages have the full setup guide.&lt;/p&gt;
</content>
    <category term="aphid"/>
    <category term="release"/>
  </entry>
  <entry>
    <title>Creating a theme with Claude Design</title>
    <link href="https://aphid.lhelge.se/blog/theme-creation-claude-design/" rel="alternate" type="text/html"/>
    <id>https://aphid.lhelge.se/blog/theme-creation-claude-design/</id>
    <published>2026-04-26T00:00:00+00:00</published>
    <updated>2026-04-26T00:00:00+00:00</updated>
    <author>
      <name>LHelge</name>
    </author>
    <summary type="text">How I used Claude Design to create the default aphid theme and how to build your own theme in a similar way.</summary>
    <content type="html">&lt;p&gt;The default aphid theme is bare-bones — a white background, the content, and no styling whatsoever. Its main job is end-to-end testing. For the project’s own blog and docs I wanted something that actually looked good, and building it with aphid itself is the best kind of &lt;a href=&quot;https://en.wikipedia.org/wiki/Eating_your_own_dog_food&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;dogfooding&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;What I had in mind was a layout that worked for long-form wiki pages and short blog posts alike, with sensible typography, a sidebar for navigation, and syntax-highlighted code blocks that didn’t look like an afterthought. Rather than start from a CSS framework or copy an existing Hugo theme, I used &lt;a href=&quot;https://claude.ai&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Claude Design&lt;/a&gt; as a design collaborator.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What you see here is the result.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Claude Design has plenty of features for steering the direction of a design, but I gave it fairly free rein. The one piece of guidance I did give it was that I like the &lt;a href=&quot;https://catppuccin.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Catppuccin&lt;/a&gt; Mocha palette. Beyond that I let it lead, and iterated on what came back.&lt;/p&gt;
&lt;h2 id=&quot;try-for-yourself&quot;&gt;Try for yourself&lt;/h2&gt;
&lt;p&gt;Claude Design is included in all paid plans, though usage on the basic $10 tier is fairly limited. Even there you should be able to push through one or two designs before hitting the cap.&lt;/p&gt;
&lt;p&gt;The intended workflow is to set up a design system and feed in a lot of design-related context before you start prompting, but that’s optional. I’ve had good results with very little steering — what you do need to give Claude is a clear picture of the application’s structure and what each template is for. There are more pointers on the &lt;a href=&quot;https://aphid.lhelge.se/wiki/ai-assisted-design/&quot;&quot; class=&quot;wikilink&quot;&gt;AI-Assisted Design&lt;/a&gt; wiki page.&lt;/p&gt;
</content>
    <category term="design"/>
    <category term="themes"/>
    <category term="ai"/>
  </entry>
  <entry>
    <title>Why I built aphid</title>
    <link href="https://aphid.lhelge.se/blog/aphid/" rel="alternate" type="text/html"/>
    <id>https://aphid.lhelge.se/blog/aphid/</id>
    <published>2026-04-23T00:00:00+00:00</published>
    <updated>2026-04-23T00:00:00+00:00</updated>
    <author>
      <name>LHelge</name>
    </author>
    <summary type="text">Why I started building yet another static site generator — a clear separation between dated build-log posts and a cross-linked reference wiki, designed for documenting a long-running VW Beetle electric conversion.</summary>
    <content type="html">&lt;p&gt;When my brother and I started converting a classic VW Beetle into an electric car, I set up a blog at &lt;a href=&quot;https://bladlus.se&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Aphid EV&lt;/a&gt; to track the project and store our research — work that could easily span a decade or more. It’s always useful to have a log to fall back on when you pick up a thread after a year away.&lt;/p&gt;
&lt;p&gt;I started with a &lt;a href=&quot;https://jekyllrb.com&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Jekyll&lt;/a&gt; site published to GitHub Pages, but it didn’t take long before two distinct kinds of content started pulling in opposite directions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Progress posts:&lt;/strong&gt; build-log entries documenting what we did, what broke, and what we learned.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reference pages:&lt;/strong&gt; research notes on components, wiring diagrams, reverse-engineered protocols — material you want to read &lt;em&gt;across&lt;/em&gt;, not &lt;em&gt;through&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Blog posts fit Jekyll perfectly, but the reference material had to be shoehorned into blog form, and I kept going back to edit old posts as I learned more. What I really wanted was a wiki-like knowledge base. I’ve used &lt;a href=&quot;https://obsidian.md&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Obsidian&lt;/a&gt; for years and like the way it lets a body of notes grow over time.&lt;/p&gt;
&lt;h2 id=&quot;looking-for-alternatives&quot;&gt;Looking for alternatives&lt;/h2&gt;
&lt;p&gt;I looked at &lt;a href=&quot;https://gohugo.io&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Hugo&lt;/a&gt; and &lt;a href=&quot;https://astro.build&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Astro&lt;/a&gt;, but nothing felt quite right in terms of features, theming, or workflow. Most static site generators treat every file as either a page or a post — there’s no first-class notion of a wiki with its own navigation, backlinks, and cross-linking.&lt;/p&gt;
&lt;p&gt;So I went the route of &lt;em&gt;personal software&lt;/em&gt; — building a tailored tool for my own needs rather than stretching a general-purpose one to fit. With modern coding agents, the cost of that decision is much lower than it used to be.&lt;/p&gt;
&lt;h2 id=&quot;design-goals&quot;&gt;Design goals&lt;/h2&gt;
&lt;p&gt;The core idea is a strict separation between three content types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Blog posts&lt;/strong&gt; — date-sorted, tagged, with author metadata.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wiki pages&lt;/strong&gt; — reference material with a flat slug-based namespace, TOC generation, and backlinks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Standalone pages&lt;/strong&gt; — About, Contact, and similar nav-level pages.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cross-linking between all three is handled with &lt;code&gt;[[wiki-links]]&lt;/code&gt;: write &lt;code&gt;[[glossary]]&lt;/code&gt; anywhere and aphid resolves it to whichever file has that filename stem, whether it lives in &lt;code&gt;blog/&lt;/code&gt;, &lt;code&gt;wiki/&lt;/code&gt;, or &lt;code&gt;pages/&lt;/code&gt;. In build mode a broken link is a hard error; in serve mode it renders visibly so writing can continue uninterrupted.&lt;/p&gt;
&lt;p&gt;That cross-linking is what forces a two-pass pipeline: the first pass indexes every file to build the slug map, and the second pass renders markdown with all links already resolved.&lt;/p&gt;
&lt;h2 id=&quot;tech-stack&quot;&gt;Tech stack&lt;/h2&gt;
&lt;p&gt;aphid is written in Rust — fast builds, a single static binary, and straightforward cross-platform CI. The intended workflow is markdown files in git, a &lt;a href=&quot;https://aphid.lhelge.se/wiki/deployment/&quot;&quot; class=&quot;wikilink&quot;&gt;Deployment&lt;/a&gt; workflow in GitHub Actions, and GitHub Pages for hosting. The same setup should work equally well on GitLab, Codeberg, or any other platform with CI and static hosting.&lt;/p&gt;
&lt;p&gt;More on the design and internals is in the &lt;a href=&quot;https://aphid.lhelge.se/wiki/&quot;&quot;&gt;wiki&lt;/a&gt;. The source is on &lt;a href=&quot;https://github.com/LHelge/aphid&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
</content>
    <category term="aphid"/>
    <category term="aphid-ev"/>
    <category term="design"/>
  </entry>
</feed>
