Reversing lookup order of partials (inline and files)?

Would it be possible to change the lookup order so that inline partials overrides a partial file with the same path/name?

Currently, a file in the partial folder seem to override a partial that is defined inline, which messes with a use-case I have been exploring for a while.

Please raise an issue on GitHub, referencing this topic.

Workaround

Assuming you have created partials/foo.html, omit the extension when calling the partial, and when defining the inline partial.

layouts/_default/baseof.html

{{ partial "foo" . }} 
{{ define "partials/foo" }}
  ...
{{ end }}

With this syntax, the inline partial will be used, falling back to partials/foo.html.

I tried removing the suffix (.html) when defining and calling the partial, but the file is still used before the inline definition.

I’ll raise an issue on Github :+1:

I’d like to see an example to understand why this doesn’t work as I described. Please post a link to the public repository for your project, or to a minimal reproducible example. Thanks.

I have made a theme demo repo: ~rsolvang/cloudless-hugo-theme-demo: / - sourcehut git

Note: Use the “partials” branch! EDIT: Also note that the theme is a git submodule which might need to be initiated (depending on your global git config).

Sorry, it works! I had not removed the suffix in the template file (section.html).

So how much of a hack is this? In the documentation they have examples with the suffix. How big is the risk of this workaround wreaking my use-case in future versions of Hugo?

Darnit, it was a premature celebration. Hugo crashes on some pages (single pages it seems) when the suffix is removed.

Errors
Failed to render "/blog/more-content/":

Failed to render pages: render of "page" failed: execute of template failed: template: _default/single.html:18:4: executing "_default/single.html" at <partial "main" .>: error calling partial: execute of template failed: template: partials/main.html:5:4: executing "partials/main.html" at <partial "main/content/below" .>: error calling partial: execute of template failed: template: _default/section.html:7:20: executing "partials/main/content/below" at <.Paginator.Pages>: error calling Pages: runtime error: invalid memory address or nil pointer dereference

You have a different problem.
The error is not related to whether or not the partial call/definition contain a suffix.

  1. Delete layouts/partials/main/content/below.html
  2. Change your calls/definitions to include suffix. Same error.

Can this error be related to the fact that I define the inline partials in another file than I call the partial, or the fact that I am nesting the partials multiple times (or both)?

The problem: you are invoking pagination from single.html.

See https://gohugo.io/templates/pagination/

Hugo supports pagination for your homepage, section pages, and taxonomies.

Think about it. A regular page doesn’t have a page collection.

I invoke .Paginator.Pages in my section.html but not from in my single.html (or am I missing something)?

EDIT: But you are correct in that removing the .Paginator and only leaving the .Pages (in the section.html) is getting rid of the error!

Can you supply a working example again?

git clone --recurse-submodules https://git.sr.ht/~rsolvang/cloudless-hugo-theme-demo
cd cloudless-hugo-theme-demo/
git checkout partials
hugo

Error: module “testchild” not found…

If you do a git pull in both the cloudless-hugo-theme-demo/ (main) folder and the /themes/cloudless/ (theme/submodule) folder, it should not throw errors. Make sure both are on the partials branch.

Unfortunately the problem persists: the partial file (or first definition in baseof.html) takes precedence over partial definitions made in other template files. It only worked for a moment, but when I started hugo serve again, it gave errors, complaining about missing partials/main/content/below.html – as expected, as I have renamed this file to below.html-test. Adding a partial definition for this file in baseof.html makes the site build for now.

Had the lookup order been reversed, it might have worked as I want it to.

Ok, so I did some further testing and realized that inline partials might behave slightly different then what I expected.

In my baseof.html I call on several partials that in turn calls on other partials – nested partials. Most of these partials are “placeholders” intended to make it possible add additional code from a “child theme” that builds on top of this one, the “parent theme”.

To avoid that Hugo complains about missing partials, I have tried creating empty partial files in the partial/ folder or making empty inline partials (kind of like declaring an empty variable). Both methods fix the errors regarding missing partials, but the emtpy files in the partials folder takes precedence over all other attempts to define an inline partial, as discussed in my first post in this thread.

And then we arrive at the point where I might have made a wrong assumption about how inline partials behave. I expected an inline partial defined in section.html to affect only section.html, but I realize now that Hugo actually stores this partial and use it everywhere this definition is called. In my case this means that the inline partial I have defined in section.html will be loaded on all pages of my theme (including single.html etc) – because these partials are ultimately called in my baseof.html.

My expectation was that inline partials behaved more like a blocks, with the possibility to make isolated changes to specific parts of my site.

Is what I’m describing above correct?

Yes. That’s why I told you:

Also, see https://gohugo.io/templates/partials/#inline-partials

But remember that template namespace is global, so you need to make sure that the names are unique to avoid conflicts.

Thanks for your patience with my ignorance, things are making more sense now.

This seems to leave me with no viable way to make a Theme Component (parent/child theme) where the child can override the parent with some level of granularity. I have been down this road before with Hugo, trying to use blocks to achieve this, without success.