Files
hugoDocs/content/templates/single-page-templates.md
T

11 KiB

title, linktitle, description, date, publishdate, lastmod, categories, tags, weight, draft, aliases, toc
title linktitle description date publishdate lastmod categories tags weight draft aliases toc
Single Page Templates 2017-02-01 2017-02-01 2017-02-01
templates
page
60 false
/layout/content/
true

The primary view of content in Hugo is the single view. Hugo will render every Markdown file provided with a corresponding single template.

Single Page Template Lookup Order

You can specify type (i.e., content type) and layout in a single content file's front matter. However, you cannot specify section because this is determined based on file location (see content section).

Hugo assumes your content section and content type are the same unless you tell Hugo otherwise by providing a type directly in the front matter of a content file. This is why #1 and #3 come before #2 and #4, respectively, in the following lookup order. Values in angle brackets (<>) are variable.

  1. /layouts/<TYPE>/<LAYOUT>.html
  2. /layouts/<SECTION>/<LAYOUT>.html
  3. /layouts/<TYPE>/single.html
  4. /layouts/<SECTION>/single.html
  5. /layouts/_default/single.html
  6. /themes/<THEME>/layouts/<TYPE>/<LAYOUT.html
  7. /themes/<THEME>/layouts/<SECTION/LAYOUT.html
  8. /themes/<THEME>/layouts/<TYPE>/single.html
  9. /themes/<THEME>/layouts/<SECTION>/single.html
  10. /themes/<THEME>/layouts/_default/single.html

Single Page Template Lookup Examples

The following examples assume two things:

  1. The project is using the theme mytheme, which would be specified as theme: mytheme or theme = "mytheme in the project's config.toml or config.yaml, respectively.
  2. The layouts and content directories for the project are as follows:
.
├── content
│   ├── events
│   │   ├── _index.md
│   │   └── my-first-event.md
│   └── posts
│       ├── my-first-post.md
│       └── my-second-post.md
├── layouts
│   ├── _default
│   │   └── single.html
│   ├── posts
│   │   └── single.html
│   └── reviews
│       └── reviewarticle.html
└── themes
    └── mytheme
        └── layouts
            ├── _default
            │   ├── list.html
            │   └── single.html
            └── posts
                ├── list.html
                └── single.html

Now we can look at the front matter for the three single-page content (i.e..md) files.

{{% note "Three Content Pages but Four Markdown Files?" %}} _index.md may seem like a single page of content but is actually a specific kind in Hugo. Whereas my-first-post.md, my-second-post.md, and my-first-event.md are all of kind page, all _index.md files in a Hugo project are of kind section and therefore do not submit themselves to the single page template lookup. Instead, events/_index.md will render according to its section template and respective lookup order. {{% /note %}}

my-first-post.md

{{% code file="content/posts/my-first-post.md" %}}

---
title: My First Post
date: 2017-02-19
description: This is my first post.
---

{{% /code %}}

When it comes time for Hugo to render the content to the page, it will go through the single page template lookup order until it finds what it needs for my-first-post.md:

  1. /layouts/UNSPECIFIED/UNSPECIFIED.html
  2. /layouts/posts/UNSPECIFIED.html
  3. /layouts/UNSPECIFIED/single.html
  4. /layouts/posts/single.html
    BREAK
  5. /layouts/_default/single.html
  6. /themes/<THEME>/layouts/UNSPECIFIED/UNSPECIFIED.html
  7. /themes/<THEME>/layouts/posts/UNSPECIFIED.html
  8. /themes/<THEME>/layouts/UNSPECIFIED/single.html
  9. /themes/<THEME>/layouts/posts/single.html
  10. /themes/<THEME>/layouts/_default/single.html

Notice the term UNSPECIFIED rather than UNDEFINED. If you don't tell Hugo the specific type and layout, it makes assumptions based on sane defaults. my-first-post.md does not specify a content type in its front matter. Therefore, Hugo assumes the content type and section (i.e. posts, which is defined by file location) are one in the same. (Read more on sections.)

my-first-post.md also does not specify a layout in its front matter. Therefore, Hugo assumes that my-first-post.md, which is of type page and a single piece of content, should default to the next occurrence of a single.html template in the lookup (#4).

my-second-post.md

{{% code file="content/posts/my-second-post.md" %}}

---
title: My Second Post
date: 2017-02-21
description: This is my second post.
type: review
layout: reviewarticle
---

{{% /code %}}

Here is the way Hugo's traverses the single-page lookup order for my-second-post.md:

  1. /layouts/review/reviewarticle.html
    BREAK
  2. /layouts/posts/reviewarticle.html
  3. /layouts/review/single.html
  4. /layouts/posts/single.html
  5. /layouts/_default/single.html
  6. /themes/<THEME>/layouts/review/reviewarticle.html
  7. /themes/<THEME>/layouts/posts/reviewarticle.html
  8. /themes/<THEME>/layouts/review/single.html
  9. /themes/<THEME>/layouts/posts/single.html
  10. /themes/<THEME>/layouts/_default/single.html

The front matter in my-second-post.md specifies the content type (i.e. review) as well as the layout (i.e. reviewarticle). Hugo finds the layout it needs at the top level of the lookup (#1) and does not continue to search through the other templates.

{{% note "Type and not Types" %}} Notice that the directory for the template for my-second-post.md is review and not reviews. This is because type is always singular. {{% /note%}}

my-first-event.md

{{% code file="content/events/my-first-event.md" %}}

---
title: My First
date: 2017-02-21
description: This is an upcoming event..
---

{{% /code %}}

Here is the way Hugo's traverses the single-page lookup order for my-first-event.md:

  1. /layouts/UNSPECIFIED/UNSPECIFIED.html
  2. /layouts/events/UNSPECIFIED.html
  3. /layouts/UNSPECIFIED/single.html
  4. /layouts/events/single.html
  5. /layouts/_default/single.html
    BREAK
  6. /themes/<THEME>/layouts/UNSPECIFIED/UNSPECIFIED.html
  7. /themes/<THEME>/layouts/events/UNSPECIFIED.html
  8. /themes/<THEME>/layouts/UNSPECIFIED/single.html
  9. /themes/<THEME>/layouts/events/single.html
  10. /themes/<THEME>/layouts/_default/single.html

{{% note %}} my-first-event.md is significant because it demonstrates the role of the lookup order in Hugo themes. Both the root project directory and the mytheme themes directory have a file at _default/single.html. Understanding this order allows you to customize Hugo themes by creating template files with identical names in your project directory that step in front of theme template files in the lookup. This allows you to customize the look and feel of your website while maintaining compatibility with the theme's upstream. {{% /note %}}

Example Single Page Templates

Content pages are of the type page and will therefore have all the page variables and site variables available to use in their templates.

post/single.html

This content template is used for spf13.com. It makes use of partial templates:

{{% code file="layouts/post/single.html" download="single.html" %}}

{{ partial "header.html" . }}
{{ partial "subheader.html" . }}
{{ $baseURL := .Site.BaseURL }}
<section id="main">
  <h1 id="title">{{ .Title }}</h1>
  <div>
        <article id="content">
           {{ .Content }}
        </article>
  </div>
</section>

<aside id="meta">
    <div>
    <section>
      <h4 id="date"> {{ .Date.Format "Mon Jan 2, 2006" }} </h4>
      <h5 id="wc"> {{ .FuzzyWordCount }} Words </h5>
    </section>
    <ul id="categories">
      {{ range .Params.topics }}
        <li><a href="{{ $baseURL }}/topics/{{ . | urlize }}">{{ . }}</a> </li>
      {{ end }}
    </ul>
    <ul id="tags">
      {{ range .Params.tags }}
        <li> <a href="{{ $baseURL }}/tags/{{ . | urlize }}">{{ . }}</a> </li>
      {{ end }}
    </ul>
    </div>
    <div>
        {{ if .Prev }}
          <a class="previous" href="{{.Prev.Permalink}}"> {{.Prev.Title}}</a>
        {{ end }}
        {{ if .Next }}
          <a class="next" href="{{.Next.Permalink}}"> {{.Next.Title}}</a>
        {{ end }}
    </div>
</aside>
{{ partial "disqus.html" . }}
{{ partial "footer.html" . }}

{{% /code %}}

project/single.html

This content template is also used for spf13.com and makes use of partial templates:

{{% code file="project/single.html" download="single.html" %}}

  {{ partial "header.html" . }}
  {{ partial "subheader.html" . }}
  {{ $baseURL := .Site.BaseURL }}

  <section id="main">
    <h1 id="title">{{ .Title }}</h1>
    <div>
          <article id="content">
             {{ .Content }}
          </article>
    </div>
  </section>

  <aside id="meta">
      <div>
      <section>
        <h4 id="date"> {{ .Date.Format "Mon Jan 2, 2006" }} </h4>
        <h5 id="wc"> {{ .FuzzyWordCount }} Words </h5>
      </section>
      <ul id="categories">
        {{ range .Params.topics }}
        <li><a href="{{ $baseURL }}/topics/{{ . | urlize }}">{{ . }}</a> </li>
        {{ end }}
      </ul>
      <ul id="tags">
        {{ range .Params.tags }}
          <li> <a href="{{ $baseURL }}/tags/{{ . | urlize }}">{{ . }}</a> </li>
        {{ end }}
      </ul>
      </div>
  </aside>

  {{if isset .Params "project_url" }}
  <div id="ribbon">
      <a href="{{ index .Params "project_url" }}" rel="me">Fork me on GitHub</a>
  </div>
  {{ end }}

  {{ partial "footer.html" . }}

{{% /code %}}

Notice how project/single.html uses an additional parameter unique to this template. This doesn't need to be defined ahead of time. The key can wait to be used in the template if present in the content file's front matter.

To easily generate new instances of this content type (e.g., new .md files in project/) with preconfigured front matter, use content archetypes.