Hi there,
I apologize if this is answered somewhere, but I couldn't find it -
I am creating a site with a main set of static pages, along with a blog. For instance, my directories look like this:
content
_index.md
some_page.md
- blog
some page.md
_index.md
Currently, in content/blog/_index.md I specify the index template like this:
content/blog/_index.md
+++
template = "blog/posts.html"
+++
Is it possible to specify the template for all pages that are defined with the _index.md file? Like:
content/blog/_index.md
+++
template = "blog/posts.html"
page_template = "blog/post.html"
+++
Right now I am manually defining the template in each blog page.
content/blog/2018-08-05.md
+++
title = "My blog post."
template = "blog/post.html"
date = 2018-08-06T03:42:41.845Z
+++
Thank you!
Duplicate of #159 I think.
That's something I'd like to have and would welcome a PR for
I can probably spend some time hacking at this, as I had the exact same problem.
I got a basic version working, but I'm wondering about expected behavior in nested directories. What should the meta.template field be of content/blog/another_level/page.md if I define a meta.page_template in content/blog/_index.md? Current behavior will only override the template on direct pages of a section, not indirect nested pages.
I also assume that we want to give priority to the template field in a page, and only set it to the page_template if the page doesn't define a template? This allows a user to override the rendering for a single page.
Those are good questions!
What should the meta.template field be of content/blog/another_level/page.md if I define a meta.page_template in content/blog/_index.md? Current behavior will only override the template on direct pages of a section, not indirect nested pages.
I think it makes sense to override the nested pages as well but I'm not entirely sure if people would even use that fact. Changing that later on would be a breaking change though. @piedoom @upsuper what do you think?
Looking at the book theme (https://github.com/Keats/book) this is a case where there are many subsections and it would be nice to have the page template apply to it. This particular case also raise the question of whether to support themes per section but that's another problem!
I also assume that we want to give priority to the template field in a page, and only set it to the page_template if the page doesn't define a template? This allows a user to override the rendering for a single page.
Yes, setting a template directly should override whatever setting we set in the section.
I think it makes sense to override the nested pages as well but I'm not entirely sure if people would even use that fact.
It feels right to do so too IMO. Reverting to the default theme for a subsection stays simple: just add page_template = "page.html" to the _index.md and the default will be restored for that subsection (and its nested sections).
The alternative would be to manually specify the theme for all subsections, but this feels wrong. I would prefer Gutenberg to do the application of the themes recursively automatically, and restore the default template when necessary.
Two more questions:
next?site component to verify the template gets overridden?This particular case also raise the question of whether to support themes per section but that's another problem!
I think it's more or less the same question. There's some fundamental principles about what a page or section is (and how it should inherit properties) that have to be decided, and have great consequences for the way to organize content and templates.
Hugo for instance has a very clear and long priority list for template lookup order. There is no per-section theme, but this can be mimicked by having a template wearing your top-level section name (can cause overlaps in names if you want to have a partials content section for instance). So i think the whole page_template = "page.html" is nice to apply recursively. But should that also apply for subsections (passing the template attribute)? Or should there be a separate section_template?
I can see at least three possible ways of dealing with this:
page_template attribute from an ancestor section which can be overriden with a template attribute on the page, or a page_template attribute of a closer parent ; sections inherit a section_template attribute from an ancestor section, which can be overriden individually with a template attribute or recursively with a section_template attributekind attribute from an ancestor section which designates a page/section template pair for this kind of content, which can be overriden individually with template and recursively with page_template and section_template (this is close to what hugo does, but hugo implies the kind from the top-level section), or even a subsection's own kind attribute (passed down recursively)single.html and a section.html. the theme attribute from a section would be passed down recursively and could be overriden with another theme or a template attributeThere's probably many more ways to deal with this but these are the three that come to my mind right now. Personally, i'd like the latter. But without hard work on implementing an overlay file system, i think that'd be a dead end where noone feels comfortable. I really like the idea that you can have different content types/kinds in your site. Manually handling this via template, page_template and section_template is feasible but i think it's worth thinking about some more. I'd be happy to have your feedback on the second proposition in the list.
There's also Custom Output Formats (#365) to consider. In this regard, i feel like content types/kinds would go in the right direction as you could not only override the default HTML template (with page_template and section_template and template) but also enable/override AMP/JSON/other on a per-kind and therefore per-section basis.
Do you want the PR based from next?
Yes, docs are automatically published on commits so I don't want to have docs of feature not yet released live.
What do you expect WRT testing? Simply add/modify some tests in the site component to verify the template gets overridden?
Some tests that the template get overriden in direct descendants, in nested one and that you can override it by setting the template in a page front-matter. At some point I hope someone will figure out a better way to write tests than adding more and more things to test_site but that's what we have right now!
I think it's more or less the same question.
Most themes, even in Hugo, are designed to be the only one so they have their homepage etc. The issue is that they will refer to macros and templates with paths that will need to be rewritten to make it work. In terms of code, that can/would be a pretty big change and it would be messy.
Or should there be a separate section_template?
Good point. My gut reaction would be that there shouldn't be a way to override nested section template from a parent one. There aren't as many sections as pages and the parent one would need to have template and section_template to both exist and be equal; not very clean. This can be revisited if we see an actual need for it later.
Do you have more information on the kind thing Hugo does? I'm not sure how that would look like in practice.
In terms of code, that can/would be a pretty big change and it would be messy.
Agreed, that's what i was arguing about my third proposal in the list (section-specific themes).
the parent one would need to have template and section_template to both exist and be equal
I don't think that's necessarily the case. Building upon the second proposal in my list, i would propose the following priority to define the template used by a page/section (upper = more priority):
template attribute (overrides anything else) is not inheritablekind/type attribute (overrides inherited attributes) is also inheritable (passed to children pages/sections)type or page_template/section_template (whichever is the "closer" parent to our current page, with priority for page/section_template attribute in case the ancestor section has both ⁽¹⁾)I think a such model would address your concerns and fit most people's expectations. Please correct me if i'm wrong! In most cases, we should only deal with type attributes but if need be you can have more granular control about the templates used.
For example, want a /books/ section homepage which is more specific than the subsections which just list content? To have a specific template on this page and still have a pair of page/section templates to pass down to children sections/pages, your _index.md could look like this:
+++
title = "The greatest revolutionary books!"
template = "books_homepage.html"
kind = "books"
+++
↑↑↑ We need to think carefully about the implications for custom output formats because template attribute takes only HTML into consideration. Maybe that's what we want. Maybe it's not. Maybe content using Custom Output Format should never use the template attribute (i rarely did when working with hugo) and a page with a specific template should be rendered only to HTML? I think we need more inspiration and feedback from other projects to make an informed decision and not rush into anything.
Do you have more information on the kind thing Hugo does?
They call it content types and they're very straightforward to use with the type attribute. The basic concept is everything you want to store in your site is usually either a piece of a content type, or a list of such pieces. the system allow you to provide a pair of single/section templates for each content type. The docs about it are not that long and really instructive: i encourage everyone to read them to find inspiration :)
The weird thing about this system is it infers content type from the top-level section by default. I don't think this is wrong (it's desirable in many cases), but it can fail in unpredictable ways: renaming your top-level section would render the section content with a more generic template (such as the default page.html) without you realizing. The type attribute explicitly avoids such traps.
The only thing i truly hate about hugo's specific implementation, though, is the whole singular/plural deal where content in an events top-level section (or of events type) would be rendered by the event templates in priority (events comes next on the lookup order). I believe the program should follow the names you give to your folders instead of enforcing english-centric pluralization rules.
⁽¹⁾ I'm not sure whether type or section/page_template should have priority when inheriting attributes. On the one hand, encouraging people to think in terms of content types is a great idea. On the other hand, without a proper type system (with inheritance and such) this can be burdensome to have to maintain many specific content types. Manually overriding the page template of a content type (without applying the template attribute everywhere) should be possible. For example, if you want your games section to borrow books section template, but have a different page template. So without proper support for theme components i'd go with priority for the section_template and page_template as they are more specific.
Having read a bit from the Hugo docs (thanks for the link @paulcmal ), I think this is a case of Hugo trying to do too much, especially with regards to what's called theme components.
Hugo is trying to cater to every usecase under the sun and it ends up being too complex for people (like me) wanting to use it for a somewhat basic usecase. Looking at this recent HN thread https://news.ycombinator.com/item?id=17942395 it seems I'm not the only one having trouble understanding it. Gutenberg aims to be much simpler to use, which means some features of Hugo are definitely going to be out of scope. Theme components are an example of that: neat on the surface but looks pretty terrible from a user perspective. At this point I would rather spend 20min to copy a theme in my templates folder and customise it directly: that would probably be faster than trying to make sense of the various rendering templates priorities.
To get back to the topic, it looks like the needs for content types is pretty much eliminated by page_template applying recursively and it is much simpler to understand. The only troublesome point is the section template. I'm guessing in some cases you might have a few subsections where you want to apply a common template, but that can be added later easily if it becomes really needed and for now it would work by copy pasting one line.
Theme components are an example of that
Well they're an overlayfs hack because hugo doesn't have a proper templating/macro/plugin system. I believe the use-cases they addressed could be handled in different and more elegant ways. For example, with theme-level inheritance (child themes) and/or with a separate folder for template bundles (such as plugins/) that would be both usable and over-ridable by the current theme and the site's templates.
But yes, having a config-defined arbitrary depth/order of priorities for templates is really confusing and potentially error-inducing.
it seems I'm not the only one having trouble understanding it
I see more people complaining about the inconsistencies of hugo's templating engine (« an implicit horrific mess with fucked up (il)logic »), not about the actual features. Although i do agree some features are not necessarily useful, and they surely don't add up to a global coherent design that's easy to grasp and deal with.
Gutenberg aims to be much simpler to use, which means some features of Hugo are definitely going to be out of scope.
Simplicity for day-to-day usage is really important indeed. Personally i don't think it means sacrificing features. It takes time and attention to build a simple, robust and coherent design, which the hugo peeps don't really care about with their "move fast and break things" attitude (which is actually good for us because it gives real-world feedback on interesting patterns and anti-patterns).
We should take time to think about the implications of all proposed features without rushing into anything. But the foundations you laid are good: a proper template inheritance model and a macro system are the two killer-features hugo doesn't have ;)
page_template applying recursively (…) that can be added later easily if it becomes really needed and for now it would work by copy pasting one line
That's really cool, thank you for taking the time to think it through and come up with a solution that matches actual and immediate needs :+1:
In regards to #365: would you be open to having the custom output formats proposal there integrate some form of content kinds into a simple and coherent design (that incorporates i18n issues as well)? I can't promise anything but i'll sure try my best over the coming weeks :)
Simplicity for day-to-day usage is really important indeed. Personally i don't think it means sacrificing features.
Even simple features accumulate and starts to interact with each other, leading to potential confusion and users feeling lost. Not to mention the code for all of them to maintain and test. I'd rather have a tool that does the job for 80% of the users while being easy to use and reason about than a tool that works for everyone but isn't as easy.
But the foundations you laid are good: a proper template inheritance model and a macro system are the two killer-features hugo doesn't have ;)
There are downsides with themes though: include currently doesn't work and blocks inheritance doesn't work as you expect them to (see https://github.com/Keats/gutenberg/issues/361 for an example which is not fixable afaik).
Most of the time I would recommend to just cp the templates/static/sass folder of a theme and skip themes altogether if you intend to tweak them.
Does your proposed changes for #365 change this feature? I still haven't fully understood custom output formats
page_template is now in the next branch and works recursively if you want to try it!
Wow, that's great, thanks for the efforts! I'll provide real-world feedback next time i build a site with zola :)
Most helpful comment
page_templateis now in thenextbranch and works recursively if you want to try it!