Skip to content

Conversation

@bep
Copy link
Member

@bep bep commented Apr 21, 2025

Closes #13636

@jmooring
Copy link
Member

I expect this test will pass because the first two rows of the table in this comment are constant.

@bep
Copy link
Member Author

bep commented Apr 21, 2025

I expect this test will pass because the first two rows of the #13636 (comment) are constant.

I obviously don't understand your failing test case, then. Oh, well, it's open source, maybe someone else will.

@bep bep force-pushed the fix/order-13636 branch from 87dec2f to d67fd8d Compare April 22, 2025 10:01
@bep bep changed the title tpl: Add a test case Apr 22, 2025
{"nn", "all.en.html", "all.nn.html", "single.html", "single.html", "single.html", ""},
{"nn", "all.en.html", "all.nn.html", "single.nn.html", "single.nn.html", "single.nn.html", ""},
{"nn", "single.json", "single.nn.json", "all.json", "", "", "single.nn.json"},
{"nn", "single.json", "single.en.json", "all.nn.json", "", "", "single.json"},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jmooring OK, so I finally understood what the issue was about, and you were right, there were some issues to be fixed. I'm not sure if the above table matches your table, but it's stable. The only question I had after this was the line above:

{"nn", "single.json", "single.en.json", "all.nn.json", "", "", "single.json"},

For lang nn we now prefer single.json over all.nn.json, which in my head makes the most sense, but I'm not entirely sure.

Anyway, thanks for the bug report (I thought we had decent test coverage on this ....), and I would appreciate if you could take this branch for a spin.

@bep bep force-pushed the fix/order-13636 branch from d67fd8d to d145392 Compare April 22, 2025 10:09
@jmooring
Copy link
Member

jmooring commented Apr 22, 2025

Thanks for looking into this. I'm glad you were able to find the problem.

Initial testing

The lookup order (highest to lowest specificity) is now stable:

page.en.html
page.en.html.html
page.html
page.html.html
single.en.html
single.en.html.html
single.html
single.html.html
all.en.html
all.en.html.html
all.html
all.html.html

Regarding your question:

  • In the list above, should page.html be chosen before single.en.html?
  • In the list above, should single.html be chosen before all.en.html?

I suppose you could argue either way, but I would leave it as is. The behavior is easily described: page kind and layout standard have higher specificity than language.

Terminology guidance

I would appreciate your guidance regarding terminology. Technically we are "weighting" various factors. When we describe weighting behavior with pages, menu entries, output formats, and sites, we say "the heavier items sink to the bottom while the lighter items float to the top."

So, instead of using words like "specificity "or "priority", should we use the word "weight"? If yes, would it make sense to present list examples like the one above in order of lightest (top) to heaviest (bottom), meaning the first chosen would be at the bottom of the list? That's the opposite of the way we present these list today.

My guess is that we will end up using both "weight" (and its derivatives) and "specific" (and its derivatives) together.

Thoughts?

Adding front matter "layout" to the mix

When I add a layout field to front matter, the stable lookup order is:

mylayout.page.en.html
mylayout.page.en.html.html
mylayout.page.html
mylayout.page.html.html
mylayout.en.html
mylayout.en.html.html
mylayout.all.en.html
mylayout.all.en.html.html
mylayout.html
mylayout.html.html
mylayout.all.html
mylayout.all.html.html
mylayout.list.en.html
mylayout.list.en.html.html
mylayout.list.html
mylayout.list.html.html
mylayout.single.en.html
mylayout.single.en.html.html
mylayout.single.html
mylayout.single.html.html
---------------------------- from here down same as before (good)
page.en.html
page.en.html.html
page.html
page.html.html
single.en.html
single.en.html.html
single.html
single.html.html
all.en.html
all.en.html.html
all.html
all.html.html

The bit above the line doesn't look right to me. At a minimum, I don't think there should be any "list" templates in the lookup order for rendering a regular page. But even if you remove those, the weighting above the line seems to different than the weighting below the line.

@bep
Copy link
Member Author

bep commented Apr 22, 2025

When I add a layout field to front matter, the stable lookup order is.

I'm not sure how you determine the "lookup order" in the above. The thing is,

  • The template path gets parsed (kind, language, output format, media type, layout) when we parse the templates. We do this for all types of templates, including base templates.
  • The layout in your examples above is the left-most unknown identifier (dot separated)
  • There can be only 1 layout in a filename, so mylayout.all.html is the same as mylayout.html
  • If you have multiple variants like the above, the first one will win (in the order given by the file system, which I'm pretty sure is lexicographically).
  • This means that mylayout.list.html may be chosen for a single page, but not because of the "lookup order".

I'm in the process of undoing the mess I created with the dot vs the content files/resources, but I'm not prepared to doing any drastic with the above. In Hugo <= 0.45 we

  1. blindly parsed all templates and inserted them using their layouts relative path.
  2. then at lookup time we constructed all relevant permutations of layout/kind/... and returned the first found.

Now we:

  1. Do the indexing job at parsetime.
  2. Then at "lookup time" we (for page layouts and shortcodes):
    1. Walk the tree down to the current Page's path.
    2. For each node, we look for a better match based on some weight groups.

As to documentation and your example:

So, instead of using words like "specificity "or "priority", should we use the word "weight"? If yes, would it make sense to present list examples like the one above in order of lightest (top) to heaviest (bottom), meaning the first chosen would be at the bottom of the list? That's the opposite of the way we present these list today.

My general thought here is that we could use the two terms weight and distance and the list of identifiers we consider (page kind, custom layout, standard layout, language, output format, media type) but without going into details about how we weigh each element.

And instead of "ordered lists" I think it would be more useful with.

  1. One representative layouts folder.
  2. And below that (maybe) a table or two with 1) A page path, kind ... 2) The template resolved 3) Why it was resolved to that template.

As to 3) I guess there are a couple things that's useful to know:

  • Kind is weighted higher than any of the standard layouts (e.g. section.html vs list.html), unless the template has shorter distance to the Page's path. This means that /layouts/foo/bar/list.html will be picked before /layouts/section.html for a Page with path /foo/bar.

Not sure how useful the above is, but I guess it's my 50 cents about this at the moment.

@bep bep merged commit 6d69dc8 into gohugoio:master Apr 22, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants