08 – The home page layout

Last Updated: Jul 7, 2022

In previous lessons, we learned how to create a page layout to display a list of content in each of our sections. In Hugo, there are different Kinds of list pages, including section pages, taxonomy pages, and the Home page.

In our pets website, the list template we created is used by the home page. If you go to the home page of our pets website, you’ll see a list of the dogs and cats articles we’ve created.

Usually a home page will have its own design, so defaulting to the list layout is probably not what we want.

In this lesson, we’ll create a simple layout for our home page, learn how to add content to it, and also introduce the concept of template lookup order.

Creating a home page template

Let’s start by creating the basic template for our home page. Fortunately, because we now have a base template, our home page template can be simple. Home page templates have a filename of index.html:

vim layouts/_default/index.html

Add the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{{ define "main" }}
<header>
	Home Page
</header>

<p>{{ .Content }}</p>

<div>
	<ul>
	{{ range .Site.Sections }}
	<li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
	{{ end }}
	</ul>
</div>
{{ end }}

Finally, let’s create a page using hugo new so that we can publish content to the home page. (Remember that we first used this command in our Hello World exercise.)

There’s a special naming convention for content pages used by List layouts: _index.md. Because this is for the home page, it’s located in the root directory. You can also create _index.md for section pages. For example, if you needed a content page for the cats List page, you would use hugo new cats/_index.md.

Create the _index.md page:

 hugo new _index.md

… and then add the following content (your date will be different, of course:

1
2
3
4
5
6
7
8
9
---
title: "Hugo's World of Pets - Home"
date: 2022-08-01T14:56:34-04:00
draft: false
---

Welcome to Hugo's World of Pets, where you can learn about any type of pet (as long as they are a cat or dog).

Click on a category below to learn about your favorite pet.

Once you’ve created these files, you can visit the home page, and you should see something like this:

You can see that the text content from the Markdown page is displayed in the place where we have .Content in the template.

Using the index.html template in practice

You can see that our template code doesn’t introduce any new concepts: it’s still basically a List page similar to the one we built in Chapter 6.

Even though there’s nothing really new about this example Home page in terms of code, there’s a few things to know about Home pages in Hugo:

The final point to emphasize is that you can use a Markdown file for any content you want to publish to the home page, and this is a good practice that you should follow.

Because a top-level index.html template file is used only by the Home page, you might be tempted to put everything in it, including content that you could otherwise publish in a Markdown file in the content directory.

It’s easier if everything is one one file! you might argue. While this might be true in one sense, keeping your content and code separate is a good practice in general. Programmers refer to this concept as separation of concerns.

Using Markdown for all of your content helps you to keep your code cleaner by keeping it in just your template files. This is particularly true if you have a publishing workflow where non-programmers are writing content for your website and who might be tempted to sprinkle some code into the content.

To help maintain good publishing practices, you can have your content writers use a Markdown editor, which will give them a simplified graphical user interface in which they don’t even need to know Markdown. You can find many excellent and open source Markdown editors on Github.

A quick note about lookup order

We’ve only briefly touched upon the concept of lookup order in Hugo, but it’s an important one to know and also one of the most confusing.

In our simplified project, we have four templates: a base template, a content template, a section template, and one for our home page.

All three of our page templates (content, section, and home) use the base template and define a single main code block that is inserted into it. We have a home template that overrides the list template, because the Home page is also a kind of List page.

However, lookup order and template overrides can get extremely complicated. For example, a Hugo site can have multiple base templates - one for each Kind of page. If there is a more specific base template defined for any page, Hugo will use that one.

The same goes for other types of templates. For example, our pets example site coule have a Dog- or Cat-specific List page.

In summary, Hugo templates of any Kind can be overridden by more specific templates that target a language, type, or output format. Markdown pages can also specify their template in Front Matter. When you multiple all the page Kinds in Hugo by the ways in which the template can be overriden by a more specific variation, you get a very long lookup order.

That’s exactly what you’ll find on Hugo’s Lookup Order documentation. While this type of flexibility is nice, it can also lead to difficult to maintain code if you’re tempted into creating a lot of customizations for every section of your site.

Most sites - even large ones with thousands of pages of content - can benefit by taking a minimalist approach and creating new templates only when necessary. If you avoid the temptation of creating many small customizations (as content producers often request!) you’ll find that your code is easier to maintain in the long run, and your site will likely have a more consistent UX and UI as well.

This only touches on template lookup order, and it’s a topic we’ll explore in greater depth in a future article.