Making a Hugo blog theme - Markup

This is a note on what I learned, what I thought, and what decisions I made in creating a new Hugo theme for my new blog.

Does this blog theme, what you are seeing now, look so simple that didn’t take much time and effort? Well, since I’m a newbie in front-end and web matters, I had to spend much effort on making this theme. This is why I think it’s worth starting my blog with this kind of note.

The first post in this series is about how this blog is organized by Hugo templates and how it is marked up in HTML.

Site structure

I’m going to maintain this site as a blog (made of a series of posts), so the following three kinds of pages will suffice as a starting point.

ContentPath
List of posts/ (/posts)
Post/posts/<post>
Individual page (for special contents)/about, …

Sooner or later, I may want to create another page that shows a set of posts grouped by categories or tags. But for now, I just tried making everything as simple and minimum as possible.

Hugo theme structure

Hugo team officially provides an example Hugo site, which contains a few posts as a demonstration. We can create our own theme based on this example site.

I found that the following two types of pages are enough for my blog.

Those pages lookup layouts/_default/list.html and layouts/_default/single.html as a template respectively, and share layouts/_default/baseof.html as a base template. Notably, the root page / will also look into the list template file, if its default theme template layouts/_default/index.html is absent.

Thus, as suggested in this article, I decided to deal with only the three template files baseof.html, list.html, and single.html (plus 404.html - this is under construction), and get rid of other template files from the initial theme generated by hugo new theme command. Furthermore, I removed all the partial templates like a site header or footer and moved those contents to baseof.html for simplicity.

Sectioning

In terms of HTML Living Standard, I tried to write the markup of this theme to be as semantically correct as possible and to represent the semantics of data as well as possible.

Every page in this theme has a navigation header that guides you to the top page and other static pages (currently only “About” is there). This component is coded by using <header> and <nav> elements. Also, pages should have exactly one main content marked up with <main>. To ensure this, the base template baseof.html codes the <main> element and loads a page fragment as a "main" block within it, depending on the page type.

Pages also have one or more <article> elements, which represent self-contained compositions. Especially, the list template list.html has nested <article> elements.

  • a single parent article, which represents a list of posts
  • multiple child articles, which represent a single post in the list

This is to declare that those posts are independent.

As recommended in the standard, every article in this theme has a heading element <hN>. This represents the title of a page or post and is wrapped by <header> element together with post metadata like updated time.

Speaking of the headings, it is often argued which heading level <h1><h6> we should use for various headings – site title, post title, and headings in each post. I opted not to use any headings for the site title, which can be replaced with a logo image or whatever (of course maybe not). Then I can use the top-level heading <h1> for the post title that summarizes the main content of a post. This decision disallows the use of # (top-level heading in Markdown) in the post, but it’s an acceptable limitation. I also opted not to make use of the outlining algorithm with nested <section> elements and headings with the same level, since it’s not well implemented by browsers or screen readers.