# Template Architecture
Hugo's template system uses Go templates with a cascading lookup order. Everything starts with a base template (`baseof.html`) that defines blocks child templates fill in.
## Base Templates and Blocks
A `baseof.html` defines the outer HTML shell. Child templates use `{{ define }}` to fill specific blocks.
**`layouts/_default/baseof.html`:**
```go-html-template
{{ block "title" . }}{{ .Site.Title }}{{ end }}
{{ block "styles" . }}{{ end }}
{{ block "header" . }}{{ partial "header.html" . }}{{ end }}
{{ block "main" . }}{{ end }}
{{ block "footer" . }}{{ partial "footer.html" . }}{{ end }}
{{ block "scripts" . }}{{ end }}
```
**Child overriding blocks** (`layouts/_default/single.html`):
```go-html-template
{{ define "title" }}{{ .Title }} | {{ .Site.Title }}{{ end }}
{{ define "main" }}
{{ .Content }}
{{ end }}
```
### Base template lookup order
1. `layouts//.html` → e.g., `layouts/post/single.html`
2. `layouts//baseof.html` (section-specific base)
3. `layouts//baseof.html` (type-specific base)
4. `layouts/_default/baseof.html` (fallback)
5. `themes//layouts/...` (same order)
Source: [Hugo docs — lookup order](https://gohugo.io/templates/lookup-order/)
## Template Lookup Order (Full)
Hugo selects the most specific template based on page parameters. Parameters applied in order of specificity:
| Parameter | Description |
|-----------|-------------|
| **Kind** | `home`, `page`, `section`, `taxonomy`, `term` |
| **Layout** | Set in front matter via `layout:` field |
| **Output Format** | Name (e.g. `rss`) and suffix (e.g. `xml`) |
| **Language** | Language tag in filename (e.g., `index.fr.amp.html`) |
| **Type** | Value of `type` in front matter, else root section name |
| **Section** | Relevant for `section`, `taxonomy`, `term` kinds |
**Targeting specific pages** — set both `type` and `layout` in front matter:
```yaml
---
title: Contact
type: miscellaneous
layout: contact
---
```
This renders via `layouts/miscellaneous/contact.html`.
The project's `layouts/` directory always wins over the theme's `layouts/`. Templates interleave between project and theme — the most specific match wins regardless of location.
## Partials
Partials live in `layouts/partials/` and are called with the dot (`.`) passing full page context:
```go-html-template
{{ partial "header.html" . }}
{{ partial "nav.html" (dict "menu" .Site.Menus.main "current" .) }}
```
Use `dict` to pass custom data instead of the full page context — saves memory and avoids unnecessary re-renders.
## Partial Decorators (v0.154.0+)
Reusable wrapper components that enclose template content using `templates.Inner`:
**Calling template:**
```go-html-template
{{ with partial "components/wrapper.html" . }}
Everything in this block will be wrapped.
{{ .Content | transform.Plainify | strings.Truncate 200 }}
{{ end }}
```
**Decorator definition** (`layouts/partials/components/wrapper.html`):
```go-html-template
{{ templates.Inner . }}
```
This pattern replaces what previously required inline partials or duplication — partial decorators compose like higher-order components.
Source: [Hugo docs — partial decorators](https://gohugo.io/templates/partial-decorators/)
## Page-Level Theming
### Section-Specific Layouts
Create `layouts//` directories for section-specific templates:
```
layouts/
├── _default/
│ ├── baseof.html
│ ├── list.html
│ └── single.html
├── posts/
│ ├── list.html
│ └── single.html
└── projects/
└── single.html
```
### Type/Kind Switching
Set `type` in front matter to use a different layout directory:
```yaml
---
title: About
type: docs
---
```
This looks in `layouts/docs/` instead of the default section.
### Archetype Patterns
Archetypes define content defaults for `hugo new`. Directory structure maps to content paths:
```
archetypes/
├── default.md # Default archetype (hugo new post/my-post.md)
├── posts.md # Section-specific (hugo new posts/my-post.md)
└── projects/
├── banner.png # Files alongside the archetype
└── index.md # Creates a leaf bundle
```
**Archetype template:**
```yaml
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
tags: []
---
```
### Layout Param
Override which template renders a page without changing its type:
```yaml
---
title: "My Page"
layout: "wide"
---
```
Renders `layouts//wide.html` instead of `layouts//single.html`.
### Pitfall: `block` in partials conflicts with `define` in page templates
`block` and `define` share the same Go template namespace. A `{{ block "title" . }}` in a partial (e.g. `head.html`) conflicts with a `{{ define "title" }}` in a page template, producing `"partials/head.html: template: multiple definition of template 'title'"`.
**Fix:** Do not use `block` in partials. Use direct template expressions instead:
```go-html-template
{{- /* Good: partial without block */ -}}
```
Leave `block` only in `baseof.html` for child templates to fill via `define` at the page level.