bobthecow/mustache.php — pull request #130 by bobthecow (2013-01-13 22:25:29+00:00)
Title: Implement template inheritance via `{{% BLOCKS }}` pragma.

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 `#`.

```html+jinja
{{% BLOCKS }}

{{$ title }}My Alsome Site{{/ title }}

{{$ stylesheets }}

{{/ stylesheets }}

{{$ header }}

Welcome to My Alsome Site

{{/ header }}

{{$ content }}

Hello, World!

{{/ content }}

{{$ scripts }}

{{/ scripts }}

```

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 is then be extended by other sub-templates, which declare their intention by adding a `parent=layout` to the `{{% BLOCKS }}` pragma tag:

```html+jinja

{{% BLOCKS parent=layout}}

{{$ title }}My Alsome Page{{/ title }}

{{$ stylesheets }}

{{/ stylesheets }}

{{$ header }}

My page has some items!

{{/ header }}

{{$ content }}

{{# items }}

{{ name }}

{{/ items }}

{{/ content }}
```

Upon rendering this `page.mustache`, the subtemplate blocks will be substituted for the parent blocks, resulting in (approximately) this:

```html+jinja

My Alsome Page

My page has some items!

{{# items }}

{{ name }}

{{/ items }}

```

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 }}`:

```html+jinja
{{$ content }}

{{$ main }}{{/ main }}

{{$ complimentary }}{{/ complimentary }}

{{/ content }}
```

Then sub-subtemplates could choose to override just the `{{$ main }}` block, while leaving `{{$ content }}` and `{{$ complimentary }}` intact.