You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{#>layout}}{{#*inline"title"}}My title{{/inline}}{{#*inline"nav"}}
My navigation
{{/inline}}{{#*inline"content"}}
My content
{{/inline}}{{#*inline"scripts"}} <script>...</script>{{/inline}}{{/layout}}
Templates using the layout must specify all inline templates, or else rendering will throw an exception. To make specifying a certain inline template optional, we can use partial blocks as follows:
The home template would then pass this parameter via {{#> layout title="My title"}}. *On a side note, we could create a helper to shorten the with-else syntax to something along the lines of {{coalesce title "Default title"}}.
However, this does not work for more than one level. For example, we cannot have some common navigation which is inherited for all pages, but then replaced by a specific one inside a page template: The common navigation would always be used due to how inline templates' scoping works.
One solution to this is to call optional templates in the common layer:
This currently parses into a VariableNode(name: title, options: [Lookup(^), Quoted("Default Title")]) - we could add this without changing the parser itself - we would only overwrite the write method and have it react to the ^ operator (*and possibly others).
However, this would deviate from the official Handlebars language (where the above is a parse error!) and would increase the learning curve.
Another option without the need for modifying the parser would be a coalesce helper which:
- {{#with title}}{{.}}{{else}}Default title{{/with}}+ {{coalesce title 'Default title'}}
This helper is trivial to implement and comes in handy in a number of situations.
Solution
The typical layout makes use of inline partials as follows:
layout.handlebars:
home.handlebars:
Templates using the layout must specify all inline templates, or else rendering will throw an exception. To make specifying a certain inline template optional, we can use partial blocks as follows:
Another option is to use partial parameters, which works best for plain strings:
The home template would then pass this parameter via
{{#> layout title="My title"}}
. *On a side note, we could create a helper to shorten the with-else syntax to something along the lines of{{coalesce title "Default title"}}
.So basically, we can mimic the following:
Limitations
However, this does not work for more than one level. For example, we cannot have some common navigation which is inherited for all pages, but then replaced by a specific one inside a page template: The common navigation would always be used due to how inline templates' scoping works.
One solution to this is to call optional templates in the common layer:
This would render the Default navigation if the template does not specify a site-nav inline partial, its contents otherwise.
See also
{{!layout ...}}
and supports multiple layers of nesting.{{#block ...}
{{#extend "layout" foo="bar"}}
The text was updated successfully, but these errors were encountered: