Dynamic names - bobthecow/mustache.php GitHub Wiki

Dynamic names let a tag name be resolved from the current context. They are primarily useful for dynamic partials: choosing which partial to render based on the data being rendered.

{{> *template }}

If template resolves to article, this behaves like:

{{> article }}

The leading * is the dynamic name operator. It is not part of the context key, so {{> *template }} resolves template, not *template.

Dynamic partials

Template:

{{> *partial }}

Data:

<?php
[
    'partial' => 'message',
    'name' => 'World',
];

Partials:

<?php
[
    'message' => 'Hello, {{ name }}!',
];

Output:

Hello, World!

Dynamic names are enabled by default. To disable them, set the dynamic_names option to false:

<?php

$mustache = new \Mustache\Engine([
    'dynamic_names' => false,
]);

Polymorphic data

Dynamic partials are most useful when one list contains different kinds of items which should be rendered by different partials.

Data:

<?php
[
    'items' => [
        [
            'template' => 'text',
            'content' => 'Hello, world!',
        ],
        [
            'template' => 'image',
            'url' => 'https://example.com/foo.jpg',
        ],
    ],
];

Template:

{{# items }}
  {{> *template }}
{{/ items }}

Partials:

{{! text.mustache }}
<p>{{ content }}</p>

{{! image.mustache }}
<img src="{{ url }}">

This keeps the branching out of the template. Each variant can be represented by data plus a partial, rather than by adding another condition to every template that renders the list. Without dynamic names, the main template often grows into a set of type checks:

{{# items }}
  {{# content }}
    {{> text }}
  {{/ content }}
  {{# url }}
    {{> image }}
  {{/ url }}
{{/ items }}

The context key does not need to be named template. For example, if your data already has GraphQL-style __typename fields, you can use those values as partial names:

{{# blocks }}
  {{> *__typename }}
{{/ blocks }}

Dotted names

Dynamic names can use dot notation:

{{> *component.template }}

The dotted name is resolved completely before Mustache loads the partial. This does not push a new frame onto the context stack. The partial renders in the same context where the dynamic partial tag appeared.

Template:

{{> *component.template }}

Data:

<?php
[
    'title' => 'Hello',
    'component' => [
        'template' => 'heading',
    ],
];

Partials:

<?php
[
    'heading' => '<h1>{{ title }}</h1>',
];

Output:

<h1>Hello</h1>

Template inheritance

When template inheritance is enabled, parent tags can use dynamic names as well:

{{< *layout }}
  {{$ content }}
    <p>{{ body }}</p>
  {{/ content }}
{{/ *layout }}

The closing parent tag uses the same dynamic name as the opening parent tag.

Missing values

If the dynamic name lookup misses, nothing is rendered:

{{> *missing }}

If the lookup succeeds but the resolved partial is not found, nothing is rendered.

Limitations

Dynamic names are supported for partial tags and parent tags. They are not general-purpose variable or section dereferencing.

Dynamic names are resolved once. If template resolves to article, the article partial is rendered — even if the data also has an article key that points elsewhere. Mustache will not chase a chain like template -> article -> content.

Further reading

⚠️ **GitHub.com Fallback** ⚠️