Hi there,
this small post will briefly cover how HUGO templates lookup selects your layouts to render Markdown content.
Structure of a Hugo Site Link to heading
The most simple case is when you define a layout inside your .md content file or front matter:
---
title: "Skills"
layout: "skills"
---
HUGO engine
will search for skills.html
layout inside /layouts
directory and renders your content based on the data.
index.html
is a template for an entry point of your webpage.
List pages Link to heading
Section and taxonomies are list pages. They are rendered based on _index.md
front matter properties in the metadata file. So if you didn’t specify a layout
in the example of content/blog/_index.md
front meta as in the example above for the Skills page then layouts/_default/list.html
is used instead by a Hugo engine to render all pages in the /blog
folder.
So you may define different layouts or use base default ones for you pages or represent the same folder structure for layout templates as your content have to override default behaviour instead without the need of front matter.
- Section:
blog
andprojects
are sections because they are top-level directories incontent/
. - Taxonomy: Tags or categories assigned in front matter, like
tags: ["hugo", "static-site"]
, are taxonomies.
Single pages Link to heading
If you place a file (e.g., index.md
) directly in the root of the /content/ directory, it is treated as a single page, and Hugo uses:
layouts/_default/single.html
(default fallback for single pages).- If a content file with front matter resides in a subdirectory of /content/, Hugo considers it part of a section, and it uses the following template order:
layouts/{section}/single.html
(if defined for that section),layouts/_default/single.html
- fallback.
So here are a diagram to summarize the cases:
content/
├── index.html <- /layout/index.html
│── skills.md <- /layouts/skills.html if layout: set "skills"
├── blog/
│ ├── _index.md <- /blog/list.html or _default/list.html if no layout: set
│ ├── post1.md
│ ├── post2.md
├── projects/
│ ├── _index.md <- /projects/list.html or _default/list.html if no layout: set
│ ├── project1.md
│ ├── project2.md
├── about/
│ ├── index.md <- single.html if no layout: set
layouts/
|── _default/
| ├── baseof.html
| ├── single.html
| ├── list.html
| |-- nutrition-data.html <- some custom layout
|-- projects/
| |-- list.html
|── partials/
| ├── footer.html
│── index.html
│── skills.html <- some custom layout, no difference with the _default
Baseof layout and partials Link to heading
HUGO engine alows amazing composition of layouts for e.g. you may define a baseof.html
layout
which will a common for all pages something like this:
<html>
<head>
<link rel="icon" type="image/png" sizes="16x16" href="{{ "favicon-16x16.png" | relURL }}">
{{ if .IsHome }}
<title>{{ .Site.Title }}</title>
<meta name="description" content="{{ .Site.Params.homeDescription }}">
{{ else if eq .Type "nutrition-data" }}
<title>Example title {{ .Title }}</title>
{{ else }}
<title>{{ .Title }}</title>
<meta name="description" content="{{ if .Params.meta }}{{ .Params.meta }}{{ else }}{{ .Params.Title }} - custom page meta {{ end }}">
<meta name="robots" content="index, follow">
{{ end }}
{{ partial "head-styles.html" . }}
</head>
<body>
<header data-pagefind-ignore>{{ partial "navbar.html" . }}</header>
{{ partial "pagefind-search.html" . }}
<main data-pagefind-body>{{ block "main" . }}{{ end }}</main>
{{ partial "scroll-up-button.html" . }}
</br>
<footer>{{ partial "footer.html" . }}</footer>
</body>
</html>
Notice how cool the conditional rendering per a page based on different frontend matters like e.g. type of a layout, literally nutrition-data.html
is a custom layout.
Inside /layouts/partials
folder you may add any custom reusable html templates to include in different pages for e.g. as the footer.html
in the example
Notice {{ block "main" . }}{{ end }}
will render next layout content for e.g. list.html, single.html
Some important difference about index.md and _index.md Link to heading
Feature | _index.md |
index.md |
---|---|---|
Purpose | Defines a section or taxonomy list page. | Defines a single, standalone page. |
Context | Used for folders representing sections. | Used for standalone or leaf bundles. |
Result | Creates a list page (e.g., /blog/ ). |
Creates a single page (e.g., /about/ ). |
The lookup order ensures you only need to create templates as specific as your site requires.
Data Link to heading
To inject for example some data onto a page from a json, create a folder data, place a json file into it e.g. 2652.json
, define in your front matter json source like this:
jsonSrc: "2652"
no need to include the extension, in your html template to access the data and start reading values from keys:
{{ with index .Params.jsonSrc }}
Javascript Link to heading
in your html files you may add javascript and/or use Hugo to manipulate data provided in your front matter
I hope this information will be helpful to you, Happy Codding!