I have a question about blocks in templates and how they’re implemented:
I have a template that does not have an extends statement. It does have several block statements, such as {% block stylesheets %} and {% block javascripts %}. Let’s call it pagebuild.html.twig
Because it’s part of one module on a modular page, pagebuild.html.twig gets called with {{ module.content|raw }}.
The modular page template contains no block statements, but it extends Quark’s modular.html.twig which does contain block statements.
The block statements in pagebuild.html.twig get successfully implemented. Is that expected behavior?
@pwr, This seems to be a question that’s best resolved by getting a foundation on Twig itself.
According to Twig:
block¶
Blocks are used for inheritance and act as placeholders and replacements at the same time. They are documented in detail in the documentation for the extends tag.
I would suggest to read the following documentation:
@anon76427325 There’s nothing I can see in the documentation that explains the behavior I outlined.
Documentation as far as I can see refers only to blocks in child templates that include extends.
In the case above, the child template is called directly with {{ module.content|raw }}, and does not extend, yet its blocks are still rendered successfully. I’m wondering why, and if that’s expected or unexpected behavior.
base.html.twig (contains {% block stylesheets %}, {% block javascripts %}, {% block body %} among others)
=> modular.html.twig (extends base.html.twig, contains {% block javascripts %}, {% block body %} and others)
==>modular-extension.html.twig (extends modular.html.twig, contains only {% block content %} and uses {{ module.content|raw }} to call pagebuild.html.twig
===>pagebuild.html.twig (does not extend anything. contains {% block stylesheets %} and {% block javascripts %} which successfully render.
Is that abnormal behavior because pagebuild.html.twig doesn’t extend anything and modular-extension.html.twig doesn’t itself reference the javascript and stylesheets blocks?
Or is it normal behavior because the chain of extended templates, from base thru modular thru modular-extension creates (in a matter of speaking) an extended template that does contain all referenced blocks? That’s what I’m suspecting, but it’s not explicitly outlined in the docs that I can see
@prw, I have been pondering over your question both yesterday and today quite a bit. And I am still confused…
In order to help the reader help you and increase the chance on a response, I would kindly ask you to consider the following:
Use an informative title
Try to formulate the question as clear as possible.
Mention the theme/plugins being used.
Use properly formatted folder structures of relevant folders.
Tip: On Windows 10 you can use $ tree | clip and on Unix $ clip | clip.exe to get a nice folder tree copied to the clipboard.
@anon76427325, thanks very much for taking the time to look into this with me. You’ve pretty much understood my setup. I’ll produce below the exact relevant trees and code (abbreviated to only what’s necessary) just for clarity:
The question is whether the javascript, stylesheet, and bottom blocks in pagebuild.html.twig should be rendering—which they do. And if that is correct, what is the explanation?
@prw, Thanks for rewriting your setup and filling in the blanks. Much clearer this way!
TL;DR: Yes, blocks ‘javascript’, ‘stylesheet’, and ‘bottom’ render as expected.
As quoted before:
Blocks are used for inheritance and act as placeholders and replacements at the same time.
Blocks are only used for inheritance. Code embedded in ‘block’ tags can (but don’t have to) be overridden by inheriting (child) templates. If overridden, the content of the block tag is replaced (‘replacements’) , else the existing content (‘placeholder’) will be rendered.
Blocks are not needed if the page is not inherited. This means, the ‘block’ tags in template ‘pagebuild.html.twig’ serve no use and could be left out.
The content of the blocks are rendered normally even if not inherited.
So in answer to your question: Yes, blocks ‘javascript’, ‘stylesheet’, and ‘bottom’ render as expected.
Note: Because ‘pagebuild.html.twig’ is not inherited by ‘modular-extension.html.twig’, the ‘content’ block in ‘modular-extension.html.twig’ will override nothing. Twig is very forgiving and will not raise an error.
As a side note: Your folder structure below ‘02._main’ looks odd, both with respect to naming and existance of subfolders. Since ‘pagebuild.md’ is not a modular page I wonder what function they serve…
This makes sense, however a couple of things still mystify me:
If the javascript and stylesheet blocks serve no use in pagebuild.html.twig, I would expect their content to show up within the page body content, not in the page header. Instead, the content from the javascript block ends up in <script> ... </script> and content from the css block shows up in <style> ... </style>. Is that some kind of forgiving code-cleanup that grav is executing when it finds random style and javascript in the page content?
pagebuild.md is actually a sort-of-modular page (collection?), based on this template by @paulhibbitts from his Quark Open Publishing theme .
In the example I gave you, the javascript and css within their respective blocks actually stood for {% do assets.add('theme://js/bricklayer.min.js') %} and {% do assets.addCss('theme://css/bricklayer.css') %}.
So obviously do.assets.add was responsible for placing the javascript and css correctly in the page. It had nothing to do with blocks.
Would have been easy for you to spot if I hadn’t overlooked it as an overly specific part of my setup “not worth sharing”.