Hugo: Adding a new site directory

Previously I completed a basic Hugo install with the Blackburn theme. The default site structure contains a directory to store the various pages:

  • /content/post/

We can create subdirectories within \post to suit our needs and organise content, and that is fine. However, you may be tempted to create additional directories at the same level as \post, in which case you will need to delve into Hugo’s inner workings. In this article we will expand our site hierarchy to include an additional directory called news and link to it from the menu. In Hugo lingo, this is called a Section.

  1. First we create the new directory. This will be the name of our new section:

    mkdir /content/news
    
  2. Then we edit config.yaml and copy the existing menu section of post:

    [[menu.main]]
    name = "Posts"
    pre = "<i class='fa fa-list fa-fw'></i>"
    weight = 1
    identifier = "post"
    url = "/post/"
    
  3. Paste the copied section and edit the name, identifier, and url parameters to point to the news directory:

    [[menu.main]]
    name = "News"
    pre = "<i class='fa fa-list fa-fw'></i>"
    weight = 1
    identifier = "news"
    url = "/news/"
    

    The weight parameter determines the order the menu items are rendered. If there are multiple items with the same weight, they will be sorted alphabetically.

    The pre parameter contains the icon to display, fa-list. Check out http://fontawesome.io/icons/ for many, many more icon options.

  4. Don’t forget to create at least one page in the news directory:

    hugo new news/my-news.md
    
  5. Now start the Hugo local server

    hugo server --theme=blackburn-master --buildDrafts
    
  6. Browse to http://localhost:1313. You should see the News link in the left menu. But clicking on it gives a blank page. Or worse, an error like 404 page not found. What happened?

Add the new directory to the theme

What we’re missing is an index page for \news, similar to the one \post has. Lets dig into the blackburn-master theme and look at the \layouts\indexes directory. This directory has a single file post.html.

  1. Create a copy called news.html:

    cd \Hugo\Sites\codeooze\themes\blackburn-master\layouts\indexes
    copy post.html news.html
    
  2. Restart the Hugo local server

    hugo server --theme=blackburn-master --buildDrafts
    
  3. Browse to http://localhost:1313.

The News link should now resolve to a page containing a list of all pages in the /content/news/ directory.

Modify the home page

There’s one thing left to do. Browse back to the home page at http://localhost:1313 and you may notice something missing. The new page we created, content\news\my-news.md is not listed on the home page. Worry not:

  1. Navigate to \themes\blackburn-master\layouts and edit index.html. You should see something like this around line 9:

    {{ range ( .Paginate (where .Data.Pages "Type" "post")).Pages }}
    
  2. We want to show all pages, so modify the line:

    {{ range ( .Paginate (where .Data.Pages "Section" "!=" "")).Pages }}
    

    This will list all pages inside subdirectories of /content/ on the home page. Pages in the root directory, like /content/about.md, will not be listed.

  3. Restart the Hugo local server and browse to http://localhost:1313. The page we created inside /content/news should now be listed.

Next steps

There are of course many other customisations you can make in Hugo and to your theme. As an exercise take a look at the following files and compare the differences:

  • \themes\blackburn-master\layouts\post\single.html
  • \themes\blackburn-master\layouts\_default\single.html

Notice the same differences when viewing news.html and post.html? Hugo will use templates in the _default folder when we haven’t provided an alternative layout to use. If you want all content pages to render the same as post.html, simply copy the first file over the second one.

Alternatively, to customise just the news.html page, create a new directory:

cd \themes\blackburn-master\layouts
mkdir news

Then create the file single.html to suit your needs.

Happy organising!