Something is Escaping Me: Cannot Pick Up the Layout

Hello. I’ve been chugging merrily along build a site with Hugo - I’m a newbie here - and I thought I had a good understanding of how Hugo would pick up a new layout (I had worked through most of Hugo in Action before starting the site).

I needed to create a contact page with a specialized form on it; thus, I intended to create a new layout (themes/mine/layouts/contact/single.html) and a new leaf page bundle (content/contact/index.md). The index.md would contain some editable content, and look something like this:

title: "Contact Us"
subtitle: "We want to hear from you"
draft: false
menu:
    main:
        identifier: "contact"
        name: "Contact"
        weight: 500
        parent: ""
---

# Contact Us

You may contact NTA directly by phone during daylight hours by phone, or use the following form to send a message:

And the single.html would look something like this:

{{ define "main" }}

<div class="container mt-4">
<div class="row">
  <div class="col">
    {{ .Content }}
    <form action="...">...</form>
  </div>
</div>
</div>

{{ end }}

However, Hugo is not picking up the contact/single.html layout. It is just applying _default/single.html. I cannot for the life of me figure out how what I have misunderstood.

Versions:

hugo v0.91.2+extended darwin/amd64 BuildDate=unknown
go version go1.17.6 darwin/amd64

Thank you in advance.

content/contact/index.md

+++
title = 'Contact'
date = 2022-01-19T16:12:38-08:00
draft = false
layout = 'foo'
+++

Lookup order (first one wins):

  1. layouts/page/foo.html
  2. layouts/_default/foo.html
  3. layouts/_default/single.html

Explanation

  1. content/contact is not a section
  2. The .Kind and .Type of content/contact/index.md are page

See:
https://gohugo.io/templates/lookup-order

1 Like

I had combed the lookup-order page several times, but still must not be understanding something. I also googled and found this page (Layouts in Hugo | Hugo tutorial | CloudCannon) which seems to state pretty clearly what I am trying to do (implicit layout connections between content and theme) should work.

However, making _default/contact.html and specifying layout: contact in the front matter seems to work.

I am still somewhat confused, because from the docs, it does not appear that stating the layout in front matter is required, but I guess that’s because I don’t understand what “a section” means as jargon.

They do.

The logical “connection” is Kind, Layout, Output Format, Language, Type, or Section as described here:
https://gohugo.io/templates/lookup-order#hugo-layouts-lookup-rules

I am just being dense, then. I cannot figure out how to implicitly link content/contact/index.md to a specific layout (whether it is _default/contact.html or page/contact.html or what-not [contact/single.html, for example]). It works when I specify layout: contact in the front matter, but not otherwise.

I am looking at the page mentioned and it seems that the very first example given is what I want but cannot get to work.

With the exception of the home page[1], layouts are stored in a subdirectory (one level deep) under layouts. The subdirectory name must be _default, or match the Type or Section of the page to be rendered.

Content Type Section Description
content/contact.md page   Regular page
content/contact/index.md page   Leaf bundle
content/contact/_index.md contact contact Branch bundle

Without specifying layout or type in front matter, the lookup order for content/contact/index.md is:

  1. layouts/page/single.html
  2. layouts/_default/single.html

If you want it to use layouts/contact/single.html, specify type = 'contact' in front matter. Then the lookup order will be:

  1. layouts/contact/single.html
  2. layouts/_default/single.html

If you want it to use layouts/contact/foo.html, specify type = 'contact' and layout = 'foo' in front matter. Then the lookup order will be:

  1. layouts/contact/foo.html
  2. layouts/contact/single.html
  3. layouts/_default/foo.html
  4. layouts/_default/single.html

It might be helpful to place this at the top of your layouts as you experiment:

Kind = {{ .Kind }}<br>
Layout = {{ .Layout }}<br>
Type = {{ .Type }}<br>
Section = {{ .Section }}<br>
BundleType = {{ .BundleType }}<br>
IsPage = {{ .IsPage }}<br>
IsSection = {{ .IsSection }}<br>

  1. Home page layouts may be stored in the root of the layouts directory, or in the _default subdirectory. See https://gohugo.io/templates/lookup-order#examples-layout-lookup-for-home-page. ↩︎

3 Likes

@jmooring has given an awesome detailed answer.

@claycle Understanding all of this becomes easy once you start looking at the variables like .Kind, .Layout, etc. that he mentioned above. I had started doing the same when I first started using Hugo.

The result of that was this “bare min” theme that I created for the purpose of diagnosing some issue or just for understanding how the front matter for parsed and how some of the internal variables like .Kind, etc got set.

Here’s a dummy sandbox Hugo site I had created a while back: https://hugo-sandbox.netlify.app/ that uses that theme. See how the Kind, Layout, etc. change at the top of every page on that site.

1 Like

Thank you both for the very helpful replies. @jmooring @kaushalmodi I am making progress again.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.