This is a proof-of-concept implementation of template inheritance via blocks.
Say we have a template named layout.mustache
. This would be our generic site layout template, consisting of all the sorts of things you'd expect in a layout template. In addition, it would have a number of blocks defined. The blocks look like Mustache sections, but they're denoted with {{$ block }}
tags instead of #
.
<!-- layout.mustache -->
{{% BLOCKS }}
<!DOCTYPE html>
<html>
<head>
<title>{{$ title }}My Alsome Site{{/ title }}</title>
{{$ stylesheets }}
<link rel="stylesheet" href="/assets/css/default.css">
{{/ stylesheets }}
</head>
<body>
<header>
{{$ header }}
<h1>Welcome to My Alsome Site</h1>
{{/ header }}
</header>
<section id="content">
{{$ content }}
<p>Hello, World!</p>
{{/ content }}
</section>
{{$ scripts }}
<script src="/assets/js/default.js"></script>
{{/ scripts }}
</body>
</html>
The blocks defined here are {{$ title }}
, {{$ stylesheets }}
, {{$ header }}
, {{$ content }}
and {{$ scripts }}
.
By default, blocks merely delineate sections of the template which can be extended (replaced) in subtemplates. If the parent template itself is rendered, the block tags are simply rendered as if they are truthy sections.
This layout
template can then be extended by other sub-templates, which declare their intention by adding a parent=layout
to the {{% BLOCKS }}
pragma tag:
<!-- page.mustache -->
{{% BLOCKS parent=layout}}
{{$ title }}My Alsome Page{{/ title }}
{{$ stylesheets }}
<link rel="stylesheet" href="/assets/css/page.css">
{{/ stylesheets }}
{{$ header }}
<h1>My page has some items!</h1>
{{/ header }}
{{$ content }}
<ul>
{{# items }}
<li><a href="{{ link }}" title="{{ name }}">{{ name }}</a></li>
{{/ items }}
</ul>
{{/ content }}
Upon rendering this page.mustache
, the subtemplate blocks will be substituted for the parent blocks, resulting in (approximately) this:
<!DOCTYPE html>
<html>
<head>
<title>My Alsome Page</title>
<link rel="stylesheet" href="/assets/css/page.css">
</head>
<body>
<header>
<h1>My page has some items!</h1>
</header>
<section id="content">
<ul>
{{# items }}
<li><a href="{{ link }}" title="{{ name }}">{{ name }}</a></li>
{{/ items }}
</ul>
</section>
<script src="/assets/js/default.js"></script>
</body>
</html>
In our example, we didn't override every block: the {{$ scripts }}
block retained its default value. We could also create a new subtemplate which extends page.mustache
, say custom-page.mustache
. That subtemplate might only replace the {{$ content }}
block of page.mustache
, and inherit the rest.
Note that page.mustache
could even define new blocks. Maybe add a {{$ main }}
and {{$ complimentary }}
section inside {{$ content }}
:
{{$ content }}
<div id="main" role="main">
{{$ main }}{{/ main }}
</div>
<div id="complimentary" role="complimentary">
{{$ complimentary }}{{/ complimentary }}
</div>
{{/ content }}
Then sub-subtemplates could choose to override just the {{$ main }}
block, while leaving {{$ content }}
and {{$ complimentary }}
intact.
feature