<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hugo on JM's Site</title><link>/tags/hugo/</link><description>Recent content in Hugo on JM's Site</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Thu, 23 Apr 2026 23:43:10 +0000</lastBuildDate><atom:link href="/tags/hugo/index.xml" rel="self" type="application/rss+xml"/><item><title>CI/CD resume publication</title><link>/config/cicd-resume/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><guid>/config/cicd-resume/</guid><description>&lt;p&gt;I am terrible at word processors / editing so I build my resume &lt;a href="https://forgejo.jmopines.com/jm/resume/src/branch/main/examples/resume"&gt;with LaTeX templates&lt;/a&gt;. I gain a pretty, highly configurable resume, but it can be a pain to modify, build, share, etc. A couple weeks ago someone pointed out to me that I forgot to update my most recent role to reflect a promotion (staff software engineer, yeahh!!). I was not at home and I had to work quite a bit to only change a word in my resume. This has always been a pain to me so I figured, why not set up a CI/CD pipeline to build and publish my resume. These are the steps I took.&lt;/p&gt;</description></item><item><title>How Dates Work on This Site</title><link>/thissite/dates/</link><pubDate>Fri, 03 Apr 2026 00:00:00 +0000</pubDate><guid>/thissite/dates/</guid><description>&lt;p&gt;Every page on this site has two dates: &lt;strong&gt;Created&lt;/strong&gt; and &lt;strong&gt;Updated&lt;/strong&gt;.
Neither one is maintained by hand. Here&amp;rsquo;s the full flow.&lt;/p&gt;
&lt;h2 id="creating-a-new-page"&gt;Creating a new page&lt;/h2&gt;
&lt;p&gt;New content is created with the &lt;code&gt;new.sh&lt;/code&gt; script:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./scripts/new.sh content/thissite/my-page.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This sources &lt;code&gt;.env&lt;/code&gt; for &lt;code&gt;HUGO_IMAGE&lt;/code&gt; and &lt;code&gt;SITE_DIR&lt;/code&gt;, then runs
&lt;code&gt;hugo new&lt;/code&gt; inside the Docker container.&lt;/p&gt;
&lt;p&gt;Hugo reads the archetype template at &lt;code&gt;archetypes/default.md&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="l"&gt;+++&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="l"&gt;date = &amp;#39;{{ .Date }}&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="l"&gt;draft = true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="l"&gt;title = &amp;#39;{{ replace .File.ContentBaseName &amp;#34;-&amp;#34; &amp;#34; &amp;#34; | title }}&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="l"&gt;tags = []&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="l"&gt;+++&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At creation time, Hugo substitutes &lt;code&gt;{{ .Date }}&lt;/code&gt; with the current
timestamp and writes it into the new file&amp;rsquo;s front matter. The result
looks like:&lt;/p&gt;</description></item><item><title>Organizing This Site</title><link>/config/site-organization/</link><pubDate>Fri, 03 Apr 2026 00:00:00 +0000</pubDate><guid>/config/site-organization/</guid><description>&lt;p&gt;A reference for how this Hugo site is organized and what configuration
options are available.&lt;/p&gt;
&lt;h2 id="sections"&gt;Sections&lt;/h2&gt;
&lt;p&gt;Sections are created automatically from the directory tree under &lt;code&gt;content/&lt;/code&gt;.
Any directory with an &lt;code&gt;_index.md&lt;/code&gt; file becomes a section with its own list
page.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;content/
├── _index.md ← home page
├── about/
│ ├── _index.md ← /about/ list page
│ ├── whoami.md
│ └── now.md
├── software/
│ ├── _index.md ← /software/ list page
│ ├── ollama.md
│ └── hugo-setup/ ← page bundle (leaf)
│ ├── index.md
│ └── architecture.svg
└── config/
 ├── _index.md ← /config/ list page
 └── this-file.md
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;No config changes are needed — Hugo derives sections from the filesystem.&lt;/p&gt;</description></item><item><title>Automatic Dating with Git</title><link>/config/git-dates/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><guid>/config/git-dates/</guid><description>&lt;p&gt;Hugo can pull dates from Git history so you never have to update &lt;code&gt;lastmod&lt;/code&gt;
by hand.&lt;/p&gt;
&lt;h2 id="enable-git-info"&gt;Enable Git info&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# hugo.toml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;enableGitInfo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="configure-front-matter-date-resolution"&gt;Configure front matter date resolution&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;frontmatter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;:filename&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;:default&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;publishDate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;:filename&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;:default&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;lastmod&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;:git&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;:fileModTime&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="how-it-works"&gt;How it works&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.Date&lt;/code&gt; — tries the filename first (&lt;code&gt;2026-04-03-post.md&lt;/code&gt;), then the
&lt;code&gt;date&lt;/code&gt; field in front matter.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.Lastmod&lt;/code&gt; — uses the Git author date of the last commit that touched
the file, falling back to filesystem mtime.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.PublishDate&lt;/code&gt; — same resolution chain as &lt;code&gt;.Date&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="filename-date-formats"&gt;Filename date formats&lt;/h2&gt;
&lt;p&gt;Hugo recognizes these patterns:&lt;/p&gt;</description></item><item><title>Setting Up Hugo with Docker</title><link>/software/hugo-setup/</link><pubDate>Wed, 01 Apr 2026 00:00:00 +0000</pubDate><guid>/software/hugo-setup/</guid><description>&lt;p&gt;This article is a &lt;strong&gt;page bundle&lt;/strong&gt; (leaf bundle). Notice it lives at
&lt;code&gt;software/hugo-setup/index.md&lt;/code&gt; — not &lt;code&gt;hugo-setup.md&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="what-makes-this-a-page-bundle"&gt;What makes this a page bundle?&lt;/h2&gt;
&lt;p&gt;The directory structure looks like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;content/software/hugo-setup/
├── index.md ← this file (the page content)
├── architecture.svg ← co-located resource (image)
└── notes.txt ← co-located resource (data)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Everything in this folder &lt;strong&gt;belongs to this page&lt;/strong&gt;. Hugo treats the sibling
files as &lt;em&gt;page resources&lt;/em&gt; accessible via &lt;code&gt;.Resources&lt;/code&gt; in templates.&lt;/p&gt;
&lt;h2 id="why-use-bundles"&gt;Why use bundles?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Co-location&lt;/strong&gt;: images and files live next to the article that uses them,
not in a global &lt;code&gt;static/&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Resource processing&lt;/strong&gt;: Hugo can resize, crop, and fingerprint bundled
images at build time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Portability&lt;/strong&gt;: move or delete the folder and everything travels together.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="using-a-bundled-image"&gt;Using a bundled image&lt;/h2&gt;
&lt;p&gt;In a template you&amp;rsquo;d access it with:&lt;/p&gt;</description></item><item><title>Using Tags and Categories</title><link>/config/taxonomies/</link><pubDate>Wed, 01 Apr 2026 00:00:00 +0000</pubDate><guid>/config/taxonomies/</guid><description>&lt;p&gt;Hugo ships with two default taxonomies: &lt;strong&gt;tags&lt;/strong&gt; and &lt;strong&gt;categories&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="assigning-terms"&gt;Assigning terms&lt;/h2&gt;
&lt;p&gt;Add them to any article&amp;rsquo;s front matter:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;My Article&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;python&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;tools&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;tutorials&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="what-hugo-generates"&gt;What Hugo generates&lt;/h2&gt;
&lt;p&gt;For each taxonomy, Hugo creates:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;taxonomy list&lt;/strong&gt; page: &lt;code&gt;/tags/&lt;/code&gt; — shows all terms.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;term&lt;/strong&gt; page per value: &lt;code&gt;/tags/python/&lt;/code&gt; — lists all articles with
that tag.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="custom-taxonomies"&gt;Custom taxonomies&lt;/h2&gt;
&lt;p&gt;Define additional taxonomies in &lt;code&gt;hugo.toml&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;taxonomies&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;tag&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;tags&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;category&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;categories&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;series&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;series&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then use &lt;code&gt;series: ['my-series']&lt;/code&gt; in front matter. Hugo generates &lt;code&gt;/series/&lt;/code&gt;
and &lt;code&gt;/series/my-series/&lt;/code&gt; automatically.&lt;/p&gt;</description></item></channel></rss>