When I was updating the tutorial, I thought about adding an overview of themes because of some chatter on this forum. Entry level users seem to get confused about “layouts” versus “themes.” My take is that the notion that it is a “layout” if it’s not in the “themes” directory contributes, so it’s an unnecessary distinction. The distinction that’s important is that these “layout” files override the corresponding “themes” files.
I used “default” in the article below. It doesn’t ring quite true, though. So, I’m asking for your opinion - is there a better way to describe it? (Assuming that you’re looking at this from that same entry-level perspective.)
The Anatomy of a Theme
Hugo themes are built around a standard directory structure. Hugo relies on that structure to determine what to do with your content.
Every theme has
static/ directories. Some themes may also have
archetypes/contains files that are used by the
hugo newcommand to help create content files.
layouts/contains the template files that Hugo uses to build your HTML files from your content files.
data/contains files that the user updates to supply information to a theme.
There are two types of themes: the “default” theme and named themes. The difference is that named themes are placed in a sub-directory of the site,
themes/nameOfTheme, while the “default” theme is placed in the site’s root directory.
The Default Hugo Theme
Hugo has no opinion on what your web site should look like or what content it should contain, so when you use the
hugo new site command to create a new site, it creates an empty (and unamed theme) in the site’s root directory:
$ hugo new site hugo-0.16 $ find hugo-0.16 | xargs ls -ld drwxr-xr-x 8 mdhender wheel 272 Nov 27 11:39 hugo-0.16 drwxr-xr-x 2 mdhender wheel 68 Nov 27 11:39 hugo-0.16/archetypes -rw-r--r-- 1 mdhender wheel 107 Nov 27 11:39 hugo-0.16/config.toml drwxr-xr-x 2 mdhender wheel 68 Nov 27 11:39 hugo-0.16/content drwxr-xr-x 2 mdhender wheel 68 Nov 27 11:39 hugo-0.16/data drwxr-xr-x 2 mdhender wheel 68 Nov 27 11:39 hugo-0.16/layouts drwxr-xr-x 2 mdhender wheel 68 Nov 27 11:39 hugo-0.16/static $
This theme, the one we’re calling the “default” theme, is special because Hugo always looks there first to find files when rendering your web site.
You’ll notice that the “default” theme doesn’t include any files (the
config.toml is part of the site, not the theme). There are no files, so there are no rules, and no output in your
public/ directory when you render your site. That leads to the saying “Hugo doesn’t have a default theme.” It’s confusing at first but it should make sense by the time we’re done.
These directories, since they’re searched first, provide an easy way for end-users to override parts of a named theme. For example, if a named theme provides a template that set the heading level to 1 for articles, the user could copy that file from the named theme into these directories and change the H1 to H2. When Hugo next runs, it would find the file in the “default” theme and use it to create the site.
On the surface, that seems like odd behavior, but it’s actually a very good thing. It allows users to easily customize your theme without changing any of the files in your theme. That makes it very easy for them to update their sites when you release an upgrade to your theme since their changes are completely outside of your theme.
Named themes are created with the
hugo new theme command. By default, they’re created as sub-directories of the
themes/ directory in your site’s root directory. (Don’t worry, Hugo will create the
themes/ directory if needed.)
# show the directories created by the new site command $ find hugo-0.16 -type d hugo-0.16 hugo-0.16/archetypes hugo-0.16/content hugo-0.16/data hugo-0.16/layouts hugo-0.16/static # create a new theme named "zafta" $ cd hugo-0.16 $ hugo new theme zafta $ cd .. # show the directories created by the new theme command $ find hugo-0.16 -type d hugo-0.16 hugo-0.16/archetypes hugo-0.16/content hugo-0.16/data hugo-0.16/layouts hugo-0.16/static hugo-0.16/themes hugo-0.16/themes/zafta hugo-0.16/themes/zafta/archetypes hugo-0.16/themes/zafta/layouts hugo-0.16/themes/zafta/layouts/_default hugo-0.16/themes/zafta/layouts/partials hugo-0.16/themes/zafta/static hugo-0.16/themes/zafta/static/css hugo-0.16/themes/zafta/static/js $
themes/zafta/ for us, then added the
static/ directories for us. That’s exactly the same structure as for the “default” theme.
Hugo also created quite a few files for our theme:
$ cd hugo-0.16/themes/ $ find zafta | xargs ls -1d zafta zafta/LICENSE.md zafta/archetypes zafta/archetypes/default.md zafta/layouts zafta/layouts/404.html zafta/layouts/_default zafta/layouts/_default/list.html zafta/layouts/_default/single.html zafta/layouts/index.html zafta/layouts/partials zafta/layouts/partials/footer.html zafta/layouts/partials/header.html zafta/static zafta/static/css zafta/static/js zafta/theme.toml
The important ones are the template files, which end in
$ find zafta -name '*.html' | xargs ls -l -rw-r--r-- 1 mdhender wheel 0 Nov 27 12:06 zafta/layouts/404.html -rw-r--r-- 1 mdhender wheel 0 Nov 27 12:06 zafta/layouts/_default/list.html -rw-r--r-- 1 mdhender wheel 0 Nov 27 12:06 zafta/layouts/_default/single.html -rw-r--r-- 1 mdhender wheel 0 Nov 27 12:06 zafta/layouts/index.html -rw-r--r-- 1 mdhender wheel 0 Nov 27 12:06 zafta/layouts/partials/footer.html -rw-r--r-- 1 mdhender wheel 0 Nov 27 12:06 zafta/layouts/partials/header.html $
The template files are all empty because Hugo doesn’t have an opinion on what your site should look like. In effect, that new theme acts just like that “default” theme. The main difference is that Hugo created the most commonly used template files as a convenience to you.
Using the Default Theme
Hugo will always check first for files in the “default” theme. ?TODO? There is no way to change this behavior.
Using a Named Theme
Hugo will only use a named theme when told to do so. You can do that on the command line with “
--theme=zafta” or by adding a line to your configuration file ("
theme = "zafta").