<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Meta on PHP Boy Scout</title><link>https://blog-570662.gitlab.io/tags/meta/</link><description>Recent content in Meta on PHP Boy Scout</description><generator>Hugo -- gohugo.io</generator><language>en-gb</language><copyright>Matt Cockayne</copyright><lastBuildDate>Thu, 21 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog-570662.gitlab.io/tags/meta/index.xml" rel="self" type="application/rss+xml"/><item><title>Moving this blog off Jekyll</title><link>https://blog-570662.gitlab.io/moving-this-blog-off-jekyll/</link><pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate><guid>https://blog-570662.gitlab.io/moving-this-blog-off-jekyll/</guid><description>&lt;img src="https://blog-570662.gitlab.io/moving-this-blog-off-jekyll/cover-moving-this-blog-off-jekyll.png" alt="Featured image of post Moving this blog off Jekyll" /&gt;&lt;p&gt;The blog you&amp;rsquo;re reading used to be a Jekyll site on GitHub Pages, built on the lovely &lt;a class="link" href="https://github.com/daattali/beautiful-jekyll" target="_blank" rel="noopener"
 &gt;beautiful-jekyll&lt;/a&gt; theme. It isn&amp;rsquo;t any more: it&amp;rsquo;s Hugo now, published to GitLab Pages. The hosting move rode along with go-tool-base &lt;a class="link" href="https://blog-570662.gitlab.io/why-we-left-github-for-gitlab/" &gt;leaving GitHub for GitLab&lt;/a&gt;, but dropping Jekyll for Hugo was its own decision, and the more interesting one. Most of the migration was painless. Two bits were not, and they&amp;rsquo;re the two bits worth writing down.&lt;/p&gt;
&lt;h2 id="why-leave-jekyll"&gt;Why leave Jekyll
&lt;/h2&gt;&lt;p&gt;Jekyll hadn&amp;rsquo;t done anything wrong, exactly. beautiful-jekyll is a genuinely nice theme and the site worked fine for years. But it had started to show its age. It hadn&amp;rsquo;t seen much improvement in a long while, and keeping it building meant staying on older versions of Ruby. Ruby is a perfectly good language, just never one I&amp;rsquo;ve much enjoyed living in, and I could feel one of those fork-it-and-drag-it-up-to-date afternoons coming, the kind I&amp;rsquo;d done before and didn&amp;rsquo;t fancy repeating.&lt;/p&gt;
&lt;p&gt;So rather than patch up what I had, I asked the more interesting question: what else is out there? It came down to a shortlist of two, Astro and Hugo. Hugo won, fairly narrowly. Partly I just liked more of its out-of-the-box themes. And partly because it&amp;rsquo;s written in Go: one portable binary, no toolchain to wrangle, the sort of thing an engineer can drop onto any machine and run without a second thought.&lt;/p&gt;
&lt;h2 id="the-day-every-image-on-the-blog-tripled"&gt;The day every image on the blog tripled
&lt;/h2&gt;&lt;p&gt;The first proper snag was about where images live. Hugo would happily have let me keep Jekyll&amp;rsquo;s arrangement, one big &lt;code&gt;/assets/images/&lt;/code&gt; folder with every post linking into it by absolute path. But I&amp;rsquo;d picked the Stack theme, and Stack leans towards &lt;em&gt;page bundles&lt;/em&gt;: each post is a directory, and the post&amp;rsquo;s own images sit right next to its &lt;code&gt;index.md&lt;/code&gt;, referenced by plain relative name. The cover image becomes a resource of the post rather than a file in a shared bucket.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s a better model, and I decided to commit to it. Getting there, I managed to make a proper mess. The migration copied the old &lt;code&gt;assets/images&lt;/code&gt; across, and Hugo&amp;rsquo;s &lt;code&gt;static/&lt;/code&gt; directory wanted a copy too, and then I started moving covers into the bundles, and at one humbling point a count turned up &lt;em&gt;every image existing three times&lt;/em&gt;: once in &lt;code&gt;assets/images&lt;/code&gt;, once under &lt;code&gt;static/&lt;/code&gt;, and once in a bundle. A blog with a hundred-odd images had become a blog with three hundred-odd, most of them duplicates nobody referenced.&lt;/p&gt;
&lt;p&gt;The fix was to go all the way to the bundle model: move each post&amp;rsquo;s images into its own directory, rewrite the references from absolute &lt;code&gt;/assets/images/x.png&lt;/code&gt; paths to bare &lt;code&gt;x.png&lt;/code&gt;, and delete the two shared piles entirely. Once the images lived &lt;em&gt;with&lt;/em&gt; the posts, there was exactly one copy of each and the path was obvious. But for an afternoon the repository was a hall of mirrors, and the lesson was to pick the new tool&amp;rsquo;s model and go all the way to it, rather than carrying the old one alongside it and ending up with both.&lt;/p&gt;
&lt;h2 id="the-extended-image-that-wasnt-new-enough"&gt;The &amp;ldquo;extended&amp;rdquo; image that wasn&amp;rsquo;t new enough
&lt;/h2&gt;&lt;p&gt;The second one cost me the most time, and it&amp;rsquo;s the most transferable, so it gets the most words.&lt;/p&gt;
&lt;p&gt;Hugo comes in two flavours, ordinary and &lt;em&gt;extended&lt;/em&gt;, and the Stack theme needs extended because it compiles SCSS. So I reached for an off-the-shelf extended Hugo container image, wired it into the pipeline, and watched the build fail with an error about a template function the theme was calling that simply didn&amp;rsquo;t seem to exist.&lt;/p&gt;
&lt;p&gt;I spent far too long suspecting the theme, my config, my content. The actual culprit was a version. The image I&amp;rsquo;d grabbed was a couple of minor releases behind, and Stack v4 uses &lt;code&gt;.Site.Language.Locale&lt;/code&gt;, a Hugo feature that only landed in 0.157. The image was older than that, so the function genuinely wasn&amp;rsquo;t there, and the error was telling me the literal truth in a way I wasn&amp;rsquo;t ready to hear. &amp;ldquo;Extended&amp;rdquo; had told me the &lt;em&gt;flavour&lt;/em&gt; was right and lulled me into not checking the &lt;em&gt;version&lt;/em&gt;, which was the thing that actually mattered.&lt;/p&gt;
&lt;p&gt;The fix was to pin a specific, recent extended image rather than trusting a floating &amp;ldquo;extended&amp;rdquo; tag to be new enough. The pipeline now runs on a pinned &lt;code&gt;hugomods/hugo:debian-git-0.161.1&lt;/code&gt;, comfortably past the 0.157 the theme needs, and the build that had been failing on a missing function went green the moment the version was right. A theme has a minimum Hugo version the same way any dependency has a minimum, and &amp;ldquo;extended&amp;rdquo; is a feature flag, not a version number.&lt;/p&gt;
&lt;h2 id="what-it-comes-down-to"&gt;What it comes down to
&lt;/h2&gt;&lt;p&gt;Moving this blog from Jekyll to Hugo, and from GitHub Pages to GitLab Pages on the way, was mostly a pleasant afternoon, with two frustrations worth sharing. Commit fully to your theme&amp;rsquo;s page-bundle model rather than dragging Jekyll&amp;rsquo;s shared-assets layout along beside it, or you&amp;rsquo;ll briefly own three copies of every image. And pin your Hugo version explicitly, because a theme needs a &lt;em&gt;recent enough&lt;/em&gt; Hugo, and the &amp;ldquo;extended&amp;rdquo; label tells you nothing at all about whether yours is.&lt;/p&gt;
&lt;p&gt;If the site renders for you now, both got sorted. If it doesn&amp;rsquo;t, well, you&amp;rsquo;re reading this in a text editor, and I&amp;rsquo;ve some more debugging to do.&lt;/p&gt;</description></item></channel></rss>