I have a default list template for all my lists, located in my themes folder (/themes/<THEME>/layouts/_default/list.html
).
list.html
{{ define "main" }}
<!-- TITLE-->
{{ block "title" . }}
{{ partial "title.html" . }}
{{ end }}
<!-- CONTENT -->
{{ block "content" . }}
{{ partial "content.html" . }}
{{ end }}
<!-- PAGE LIST -->
{{ block "pages" . }}
{{ partial "pages.html" . }}
{{ end }}
<!-- FILE LIST -->
{{ block "files" . }}
{{ partial "files.html" . }}
{{ end }}
{{ end }}
baseof.html
...
<main id="main">
{{ block "main" . }}{{ end }}
</main>
...
I also have a content type called images and I want to tweak a bit how the list is displayed for it specifically, namely I want to alter the contents of the “files” block so that instead of containing:
{{ partial "files.html" . }}
It contains:
<div class="viewer"></div>
{{ partial "files.html" . }}
Soliton #0
Just create a /layout/images/list.html
file and fill it with:
{{ define "main" }}
<!-- TITLE-->
{{ block "title" . }}
{{ partial "title.html" . }}
{{ end }}
<!-- CONTENT -->
{{ block "content" . }}
{{ partial "content.html" . }}
{{ end }}
<!-- PAGE LIST -->
{{ block "pages" . }}
{{ partial "pages.html" . }}
{{ end }}
<!-- FILE LIST -->
{{ block "files" . }}
<div class="viewer"></div>
{{ partial "files.html" . }}
{{ end }}
{{ end }}
Con: Works perfectly, but now I have duplicate template code (I shouldn’t have to re-define TITLE, CONTENT, PAGE… only FILE).
Solution #1
Somehow somewhere place a {{ define "files" }}
? I don’t think you can use define
and block
with list.html however, only baseof.html.
Con: Not possible?
Solution #2
Create a files-top.html partial, place it within the “files” block like so:
...
<!-- FILE LIST -->
{{ block "files" . }}
{{ partial "files-top.html" . }}
{{ end }}
...
And let it contain:
{{ partial "files.html" . }}
And then somehow replace the contents of files-top.html for images only to:
<div class="viewer"></div>
{{ partial "files.html" . }}
But while it is possible to make a specific list.html and single.html for specific content types like images you can’t do it with partials I belive… well you can create a partial with the same name but then it would overwrite it for all content types, not just “images”.
Con: Not possible?
Solution #3
Make a files-top.html
partial with the content type label at the start (e.g. images-files-top.html
) but instead of making Hugo handle which to use you dynamically check for type specific partials using template code, e.g. :
...
{{ $custom_template := ( printf "%s-files-top.html" .Type ) }}
{{ $custom_template_path := ( printf "partials/%s" $custom_template ) }}
{{ if templates.Exists $custom_template_path }}
{{ partial $custom_template . }}
{{ else }}
{{ partial "files-top.html" . }}
{{ end }}
...
Con: Works perfectly, but perhaps there is a more “native” non-template language way to do this?
Solution #4
… ?
If there are no better solutions I’ll probably just go with Solution #3.
EDIT - An extra solution
Just define custom partials within the list type frontmatter (content/<TYPE>/_index.md) and let the list.html use that if defined.