Optional partial inclusion / partial self referencing

Hello Hugo Community,

Is there a possibility to include a partial based on its existence or not?
I am willing to use this to “implement” a template inheritance mechanism with the standard Go template language.

The second question is whether it is possible to get information about the partial itself when included? What I am typically interested in is its filename at generation time.

Note: To scope things I am currently not interested in the other template engines as I want to have a syntax that is close to html design tools, can work with.

Regards,

Bram

Currently no. It would be possible to implement, of course, but it’s not on my list.

Isn’t that implied?

{{ partial "header.html" . }} {{/* ==> partial/header.html */}}

Hi Bjørn,

Thanks for your quick response.

I got kinda template “inheritance” working.
In the partials providing the overrides I use a “self-reference” to provide extends-functionality.

See example files below…

Driver script: _default/single.html

{{ if ne "" .Type }}
{{ .Scratch.Set "block" "extends" }}
{{ partial (printf "%s.html" .Type ) . }}
{{ end }}
{{ partial "layout.html" . }}

Base layout: partials/layout.html

<html>
<body>
	<header>
		{{ .Scratch.Set "block" "header" }} {{ if not (.Scratch.Get (printf "block-%s" (.Scratch.Get "block"))) }}
		<h1>{{ .Site.Title }}</h1>
		<ul>
			<li>
				<a href="/home/">Home</a>
			</li>
			<li>
				<a href="/posts/">Posts</a>
			</li>
		</ul>
		<hr/>
		{{ else }}{{ partial (.Scratch.Get (printf "block-%s" (.Scratch.Get "block"))) . }}{{ end }} 
	</header> 
	<div id="content-wrapper">
		{{ .Scratch.Set "block" "content" }} {{ if not (.Scratch.Get (printf "block-%s" (.Scratch.Get "block"))) }}
		<i>... please override ...</i>
		{{ else }}{{ partial (.Scratch.Get (printf "block-%s" (.Scratch.Get "block"))) . }}{{ end }} 
	<div> <!-- content-wrapper -->
	<footer>
		{{ .Scratch.Set "block" "footer" }} {{ if not (.Scratch.Get (printf "block-%s" (.Scratch.Get "block"))) }}
		<hr/>
		{{ else }}{{ partial (.Scratch.Get (printf "block-%s" (.Scratch.Get "block"))) . }}{{ end }} 
	</footer> 	
</body>
</html>

Extended layout: partials/page.html

{{ if eq "extends" (.Scratch.Get "block") }}
{{ .Scratch.Set "block-content" (printf "%s.html" .Type) }}
{{ end }}
{{ if eq "content" (.Scratch.Get "block") }}
	<h2>Page - {{ .Title }}</h2>
	<i>{{ .Description }}</i>
	<p>{{ .Content }}</p>
{{ end }}

Extended layout: partials/posts.html

{{ if eq "extends" (.Scratch.Get "block") }}
{{ .Scratch.Set "block-content" (printf "%s.html" .Type) }}
{{ end }}
{{ if eq "content" (.Scratch.Get "block") }}
	<h2>Post - {{ .Title }}</h2>
	<i>{{ .Description }}</i>
	<p>{{ .Content }}</p>
{{ end }}

Note: In a similar way I implemented this for the list page leaving the layout.html untouched.

Best regards,

Bram

1 Like

I have put it to the test with a template generated by bootstrapstudio.com.

With this pattern it was really quickly to incorporate the template as I just had to identify and override the placeholders.

Example: http://hugo.bemsite.nl/

Interesting.

Today I am focussing on something that Hugo can’t do with Go templates?!

But if you did this with Hugo, the above isn’t entirely true … :slight_smile:

1 Like

You are totally right :wink:

I wrote that part before I started to experiment with the idea.

But now being able to work around this way, helps me to stay with Hugo as generator. Especially for more complex templates I like to have most of the layout in one file and I also dislike to repeat header/footer includes for different types of bodies. Potentially I should also be able to follow a similar approach with the {{ render }} command, but I think I will end up with same kinds of tricks to deal with default content when a block is not overridden.