FWIW, I assumed that I could cut up my baseof.html
template into constituent files to organise them in a more granular way… Perhaps more granularly than many users tend to do. Here’s the structrure of my layouts/
folder:
layouts/
├── _default/
│ ├── baseof.html
│ ├── list.html
│ └── single.html
├── partials/
│ ├── _global/
│ │ ├── 0-head/
│ │ │ └── primary_head.html
│ │ ├── 1-body/
│ │ │ └── primary_body.html
│ │ ├── 2-header/
│ │ │ └── primary_header.html
│ │ ├── 3-main/
│ │ │ └── primary_main.html
│ │ └── 4-footer/
│ │ └── primary_footer.html
│ └── menus/
│ ├── basic/
│ │ ├── recursion-full.html
│ │ ├── recursion-none.html
│ │ └── sectional.html
│ ├── iconographic/
│ │ └── social-media.html
│ └── special-purpose/
│ └── a11y-jump-navigation.html
├── shortcodes/
└── 404.html
Several of the partials, in turn, reference partials that are “more deeply nested”.
To explain, here is the code in two of the files above:
layouts/_default/baseof.html
<!DOCTYPE html>
<html lang="en" class="w-full h-full">
{{- partial "_global/0-head/primary_head" . }}
{{- partial "_global/1-body/primary_body" . -}}
{{- partial "debug/json.html" (dict "siteParams" .Site.Params "currentContext" site.Menus) -}}
</html>
layouts/partials/_global/1-body/primary_body.html
<body class="w-full h-full">
<div class="w-full flex flex-col md:flex-row md:flex-wrap min-h-screen">
{{- partial "menus/special-purpose/a11y-jump-navigation" . }}
{{- partial "_global/2-header/primary_header" . }}
{{- partial "_global/3-main/primary_main" . }}
{{- partial "_global/4-footer/primary_footer" . }}
</div>
</body>
layouts/partials/_global/3-main/primary_main.html
{{- block "body-global-main" . }}
<main id="main" role="main" class="body-global-main">
{{ .Content }}
</main>
{{ end -}}
What I’d been hoping to do was then define {{block "..."}}
blocks in the various partials and then “redefine” ({{define "..."}}
) them in page templates of greater specificity, only overriding/redefining blocks
that were in need of “Section” specific changes.
I found this Discourse thread because, after having setup my code as displayed above, I began working on overriding the body-global-main
block (initialised in primary_main.html
as illustrated above) in layouts/_default/home.html
… and it wasn’t working.
I can see now from @bep 's comment in this thread that the constructs {{block}}
and {{define}}
are “only meant to be used in baseof.html
templates”. For anyone who was thinking of doing something like what I was trying, here’s the page to look up “baseof” (and other such) templates: Template lookup order .
It really would be great if we could cut up our baseof.html
templates so that they are easier to parse through but, lacking that capability, for others who come across this thread, the way to go as of today is to:
- Keep ALL markup that you want to override using
{{block}}/{{define}}
constructs in a single file… - Then, simply accept that we’ll be duplicating the
baseof.html
at least a few (e.g., copy/paste inhome.html
which is what I need to do in my case) and then override in higher-specificity List/Single pages as needed.
The above doesn’t preclude a mix of cut-up of code like <head>
and opening/closing <body> </body>
tags into partial files. This should at least help keep things a bit cleaner. E.g. - snippets of what I’m doing now:
layouts/_default/baseof.html
<!DOCTYPE html>
<html lang="en" class="w-full h-full">
{{- partial "_global/0-head/baseof_head" . }}
layouts/_default/baseof.html
<!DOCTYPE html>
<html lang="en" class="w-full h-full">
{{- partial "_global/0-head/home_head" . }}
The above illustrates that I’ve moved removed the use of block
({{block "head-styles-global" . }}
) in those two partials and thus, I’m able to better control and override which JS and CSS files are used globally (in {{partial "_global/0-head/baseof_head" . }}
) by overriding the partial that is loaded in layouts/_default/home.html
to be {{- partial "_global/0-head/home_head" . }}
instead. To explain, the site’s home page will have vastly different styling and JS requirements and so, they shouldn’t be loaded with every page.
I do hope that maybe we can simply override {{block}}
with {{define}}
across “secondary” baseof templates in the future. I sorta wonder if maybe Hugo could provide this capability by defining hierarchical relationships between types of Template files like so:
- ROOT (any block defined here can be overridden in children): baseof.html (and variations thereof)
- Second-Tier: home, list, single, section, page (
{{define}}
blocks in these could then override{{block}}
definitions inbaseof.html
. Templates of this tier can also define new blocks of their own. - Third-Tier:
content/TREE-STRUCTURE
based specificity templates. E.g.content/pages
andcontent/posts
would both imply that they may have customised layouts inlayouts/pages/[list|single].html
andlayouts/posts/[list|single].html
. Third-Tier templates wouldn’t be able to define new{{block}}
blocks, they’d only be able to override blocks defined in “lower level” tier templates.
I hope this info helps others in the future!
Related threads: