Skip to content

Hugo migration#98

Draft
maxkapur wants to merge 216 commits into
masterfrom
maxkapur.github.io-hugo
Draft

Hugo migration#98
maxkapur wants to merge 216 commits into
masterfrom
maxkapur.github.io-hugo

Conversation

@maxkapur

@maxkapur maxkapur commented May 24, 2026

Copy link
Copy Markdown
Owner

Yesterday we fiddled with Zola (#97) and today we fiddle with Hugo.

This WIP includes the same demo posts/pages from before all posts and pages. Trying to maintain clean separation between the theme and content.

TODOs (many copy/pasted from that PR since they still apply):

  • KaTeX server-side rendering: See example in formats masterpost.
  • $$ ... $$ delimiters will need updating to use the custom shortcode. We can regex this
  • Try to apply the IBM Plex Math font to rendered KaTeX for overall cohesion. Is it possible to avoid the KaTeX fonts and CSS entirely?
  • Check formatting of the formats masterpost closely for parity.
  • Pagination. Set it up before fiddling with CSS!
  • Header/footer, can we port the sort_order custom functionality? Yes! weight key
  • Appropriate handling of hidden: true posts. See comments in migrate.py. The weird convention I evolved on the Jekyll site was:
    • For standalone pages, hidden means "don't include it in the menu/navbar." In Hugo, I set it up so instead inclusion in the navbar is explicit, by setting menus = ["main"] in frontmatter. The params.hidden key is dropped in the migration.
    • For posts, hidden means "don't include it in the list of posts on the home page." On the new site, I think I'm going to show just the 5 most recent post titles (without content) on the home page. We retain the params.hidden key, and will use it to mean "suppress this from the home page." They can still show in full on /posts which will include previews. The old "browse" view will go away or perhaps be relegated to the styled atom feed.
  • Old pages also had katex: true frontmatter element to indicate pages where it's needed, but migration script flagged that I was actually quite inconsistent in using this. Probably we can just drop it since katex CSS is needed on the homepage anyway and it'll be in cache.
  • Update /colophon/ :)
  • Update README
  • CSS migration. I would prefer to get away from Sass. The definitions should be easy to port. But let's see if we can structure the new CSS in a way that's easier maintain, e.g. https://jacobb.nyc/writing/how-i-write-css-in-2024. Scaffold is there but I haven't actually written the styles. Problems I have spotted:
    • Line height variance when footnote
    • Weird paragraphing spacing when list elements have multiple paragraphs
  • Done, but needs verification: Support legacy URLs for pages and posts. See CLS Korea for an example of how the aliases: frontmatter field works and note interaction with Jekyll's permalink: (which we are now going to implement as an aliases).
  • Make sure that posts and pages use the same template, handling presence/absence of date information appropriately. This was annoying to maintain separately in previous version.
  • Review licensing. CC license in the repo root is more appropriate for content than code; we might want to apply a separate license to the theme.
  • Any weird interaction with DNS path forwards or other GitHub pages sites mounted on subpaths?
  • Relative link syntax
  • Atom/RSS feed location--will it resolve at the same path? If not, can we clone it to that path to support legacy subscribers? Same path; built custom Atom template since Hugo uses RSS 2.0 by default
  • Atom/RSS feed unique post IDs. See if we can make this a permanent part of frontmatter
  • Expand lint steps. Investigate https://discourse.gohugo.io/t/tutorial-how-to-check-broken-links-in-hugo/54750
  • Check posts that have KaTeX named anchors ("tags"?) and see if there are any internal hyperlinks that broke
  • Favicon. Also include in Atom <icon>: https://validator.w3.org/feed/docs/atom.html
  • Understand how Hugo separates summary from content. It seems to respect the <!--more--> separator, but not my convention of omitting it when the post is supposed to be its own summary (i.e. appear in full on the homepage)
    • Easy workaround is to set summaryLength = 99999 in settings so that the automatic summary for posts without the delimiter is just the whole post
    • Some <!--more--> separators need manual audit: I included it inline in some paragraphs to cut off a footnote (footnotes styled weird on the old homepage). Hugo will only respect the separator if it's on its own line, and unclear how it will behave with footnotes. Investigate
  • Work around surprising behavior where if a post has a date in filename and in frontmatter, this causes the slug to parse to null. Bug affects me on the P&B interview writeup+local mirror which have the same date in filename but custom datetimes in frontmatter to force a sort order: Decouple slug inference from date resolution when using :filename in front matter config gohugoio/hugo#14971
    • Option A: Explicit slug on those posts (can add to migrate.py)
    • Option B: Forbid explicit dates (check added to migrate.py) and use weight to break ties in sort order
  • "Read more" link
  • Menu configuration to make it easy to control links in header vs. footer nav

migrate.py script, grown slowly during this process, automates most of the migration steps. Here are a few migrations I did manually:

  • Set dates and lastmods for the plain pages. Unlike posts, these never had date info in Jekyll so I pulled it in from git.
  • Make image references in content/posts/2025-12-19-perfect-match-integer-programming.md relative. (For some reason I used absolute URLs generated via {{ site.baseurl }} to embed images in this post and no others.)
  • Remove stray Jekyll comments in about.md, colophon.md, and projects.md pages
  • Correct inline KaTeX in content/posts/2024-09-24-bimatrix-game-equilibrium.md (paragraph beginning and ending in inline KaTeX regex matched as display KaTeX)
  • Convert redundant dates to weights (Option B above)

Ideas that can happen after migrating:

  • Move images into directories alongside the content that references them instead of /static/assets/images.
  • Atom feed style
  • Sitemap style (currently, due to pagination, there is no easy way to find the URL for a post by ctrl+Fing its title in the website)

@maxkapur maxkapur marked this pull request as draft May 24, 2026 16:10
maxkapur added 29 commits June 27, 2026 10:01
This seems like the cleanest way to support legacy paths. We'll
have to do it for every page, but I think I actually like that
better than an automatic rule that generates copies of the pages
at the old paths because this makes it explicit what the old URLs
were and will be easier to carry through future migrations.

Note the "automatic rule" idea mentioned above isn't possible with
hugo currently; you can only have one permalink pattern set in
hugo.toml for each post.

Also note that adding a similar alias rule for pages like
`/formatting/` that already had a `permalink:` set in Jekyll isn't
necessary. In those cases the permalink replaces the dated path so
it would never have resolved anyway. This should ease automated
migration.
Create a custom shortcode that renders inline or display mode
math depending on whether shortcode was called with inner
argument or not. Formats masterpost has an example, but we
will need to double check how robust it is to more complicated
display equations with backslash escaping etc.
Add link to the blog post I am trying to follow and migrate
default styles into that schema. Following the guide only
loosely. I don't understand CSS layers yet
Hugo manages paths within assets/ but not within static/
Doesn't look terrible but maybe we revisit the CSS question
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant