Pass partials as parameters of a template?

Hi,

I would like know whether it is possible to pass partials as parameters of another template.

The reason I need this feature is that I want to make my code DRY.

e.g.

// One template file, say: page.html

<html>
<head>
    // some code
</head>
<body>
    // some code before
    {{ partials "component-1" . }} // this part can be replaced by other components
    // some code after
</body>
</html>

Actually, I have multiple components and want to use some of them to render page.html differently.
In order not to copy the existing code for each use case, I prefer render the page.html like a function call:

{{ post/page.html partials "component-1" . }}

or if page.html is also a partial.

{{ partials page.html partials "component-1" . }}

Hope my question is clear, and feel free to ask for more details if not.
If I am missing something, please let me know.

Thank you in advance.

To clarify: I think you want to conditionally include partials. What do you need to use as the trigger to switch to a different component?

I had a similar question I was actually just about to ask but see it is very related to conditional partial inclusion.

Is there a logical test that can be done in the template to check for the existence of a partial? I realize this initially seems useless since if it is not found it will continue through the search to find one that does exist. I was just wondering if this can be tested.

If there were a function to test for the existence of a partial theme authors could actually create their own _default options and such rather than rely on content views, (which I avoid due to their limitations v.s. partials).

I have noticed that if a partial does not exist at all it generates an error similar to the following and stops the rest of the page from loading (but doesn’t crash Hugo):

ERROR: 2016/03/30 Expecting to find a template in either the theme/layouts or /layouts in one of the following relative locations [partials/types/menu/block theme/partials/types/menu/block]

Obviously the solution here is to make sure you have a partial in your theme or layout for every time you might call a partial, but I was hoping for more graceful failure when it does not find a partial.

I can’t help but wonder if the issue of theme compatibility could be alleviated by a more graceful failure to include partials.

No there isn’t. I agree that it would be nice if we could in a non-breaking way add an option to the partial template to mark it as optinal – i.e. just return empty if not found. Or, better, check if it is possible to create a silent template func that can be used to decorate (the partial stills needs to be modded, though) and silence any errors.

We also have this:

Could you create a GitHub issue?

I will admit I was really scratching my head to realize that an unfound partial stops the rest of the template code from being processed—especially after having moved to a focus on partials over content views.

Hi,
Let me clarify my question. What I want is to modularize my templates.
Say: I have three templates:

  • index.html
  • post/single.html
  • taxonomy/tags.terms.html

Their html structure looks similar, for example, like the following:

<html>
<head>
    // some code 1
</head>
<body>
    // some code 2
    {{ partials "component-x" . }} // this part can be replaced by other components
    // some code 3
</body>
</html>

These three templates use different partials. So I have to repeat the outer containing html code for each of the template.
I prefer creating a new template by combining the outer html code and partials.

e.g. I will create a template called outer.html

// outer.html

<html>
<head>
    // some code
</head>
<body>
    // some code before
    {{ . }} // use partial passed in
    // some code after
</body>
</html>

Then the three templates will be created like a function call:

// File: index.html

{{ outer.html partials "component-for-index"}}

// File: post/single.html

{{ outer.html partials "component-for-post-single"}}

// File: taxonomy/tags.terms.html

{{ outer.html partials "component-for-tags-terms"}}

I would be easier to maintain the code.
So does this feature exist in Hugo ? If not, is there any workaround ?
Thank you.

That’s much clearer. I don’t believe thats possible at the moment – I’m still a Hugo noob though.

You can obviously move a lot of the basic html elements into partials, header and footer are obvious partials. I think most people also have a head-meta partial, a workaround for the moment, albeit and ugly one, would be to move the ‘outer html’ into partials (I say ugly because you’d need to split opening and closing parts of the html and body elements – takes my back to templates in phpnuke over a decade ago. Not good memories.).

I wonder if there is anything for this in the alternate template systems Hugo supports, Ace ( https://gohugo.io/templates/ace/ ) or Amber ( https://gohugo.io/templates/amber/ ) ?

Look at bep’s site: https://github.com/bep/bepsays.com/tree/master/layouts. I think what he’s doing may help solve your problem.

He’s using the block feature (Ace and now Go 1.6 templates support this) with baseof templates to modularize his layouts. Note that the block and baseof template constructs doesn’t appear to be documented yet for Go templates. Read the Ace template docs along with this code comment for help. These features will be available in Go templates in the next Hugo release.

Thank you for the info.

Thank you. I will take a look. =)