In this article, we’ll take a close look at how context works in the Hugo static site generator. We’ll examine how data flows from content to templates, how certain constructs change what data is available, and how we can pass on this data to partials and base templates.
This article is not an introduction to Hugo. You’ll probably get the most out of it if you have some experience with Hugo, as we won’t go over every concept from scratch, but rather focus on the main topic of context and variables. However, if you refer to the Hugo documentation throughout, you may well be able to follow along even without previous experience!
We’ll study various concepts by building up an example page. Not every single file required for the example site will be covered in detail, but the complete project is available on GitHub. If you want to understand how the pieces fit together, that’s a good starting point. Please also note that we won’t cover how to set up a Hugo site or run the development server — instructions for running the example are in the repository.
If the concept of static site generators is new to you, here’s a quick introduction! Static site generators are perhaps best described by comparing them to dynamic sites. A dynamic site like a CMS generally assembles a page from scratch for each visit, perhaps fetching data from a database and combining various templates to do so. In practice, the use of caching means the page is not regenerated quite so often, but for the purpose of this comparison, we can think of it that way. A dynamic site is well suited to dynamic content: content that changes often, content that’s presented in a lot of different configurations depending on input, and content that can be manipulated by the site visitor.
In contrast, many sites rarely change and accept little input from visitors. A “help” section for an application, a list of articles or an eBook could be examples of such sites. In this case, it makes more sense to assemble the final pages once when the content changes, thereafter serving the same pages to every visitor until the content changes again.
Dynamic sites have more flexibility, but place more demand on the server they’re running on. They can also be difficult to distribute geographically, especially if databases are involved. Static site generators can be hosted on any server capable of delivering static files, and are easy to distribute.
A common solution today, which mixes these approaches, is the JAMstack. “JAM” stands for JavaScript, APIs and markup and describes the building blocks of a JAMstack application: a static site generator generates static files for delivery to the client, but the stack has a dynamic component in the form of JavaScript running on the client — this client component can then use APIs to provide dynamic functionality to the user.
Hugo is a popular static site generator. It’s written in Go, and the fact that Go is a compiled programming language hints at some of Hugos benefits and drawbacks. For one, Hugo is very fast, meaning that it generates static sites very quickly. Of course, this has no bearing on how fast or slow the sites created using Hugo are for the end user, but for the developer, the fact that Hugo compiles even large sites in the blink of an eye is quite valuable.
However, as Hugo is written in a compiled language, extending it is difficult. Some other site generators allow you to insert your own code — in languages like Ruby, Python or JavaScript — into the compilation process. To extend Hugo, you would need to add your code to Hugo itself and recompile it — otherwise, you’re stuck with the template functions Hugo comes with out-of-the-box.
While it does provide a rich variety of functions, this fact can become limiting if the generation of your pages involves some complicated logic. As we found, having a site originally developed running on a dynamic platform, the cases where you’ve taken the ability to drop in your custom code for granted do tend to pile up.
Our team maintains a variety of web sites relating to our main product, the Tower Git client, and we’ve recently looked at moving some of these over to a static site generator. One of our sites, the “Learn” site, looked like a particularly nice fit for a pilot project. This site contains a variety of free learning material including videos, eBooks and FAQs on Git, but also other tech topics.
Its content is largely of a static nature, and whatever interactive features there are (like newsletter sign-ups) were already powered by JavaScript. At the end of 2020, we converted this site from our previous CMS to Hugo, and today it runs as a static site. Naturally, we learned a lot about Hugo during this process. This article is a way of sharing some of the things we learned.
As this article grew out of our work on converting our pages to Hugo, it seems natural to put together a (very!) simplified hypothetical landing page as an example. Our main focus will be a reusable so-called “list” template.
In short, Hugo will use a list template for any page that contains subpages. There’s more to Hugos template hierarchy than that, but you don’t have to implement every possible template. A single list template goes a long way. It will be used in any situation calling for a list template where no more specialized template is available.
Potential use cases include a home page, a blog index or a list of FAQs. Our reusable list template will reside in layouts/_default/list.html
in our project. Again, the rest of the files needed to compile our example are available on GitHub, where you can also get a better look at how the pieces fit together. The GitHub repository also comes with a single.html
template — as the name suggests, this template is used for pages that do not have subpages, but act as single pieces of content in their own right.
Now that we’ve set the stage and explained what it is we’ll be doing, let’s get started!
#developer #web-development