<p><a href="https://stackoverflow.com/a/27268519/4663184">Can't be done.</a> In short, a template is either extending another template (i.e. it contains an <code>{% extends %}</code> tag anywhere in the code), or it doesn't. Twig doesn't permit the <code>{% extends %}</code> tag inside an <code>{% if %}</code> statement, which makes "conditional extending" impossible.</p>

<p>Using a ternary operation to conditionally select <em>which template to extend</em> is allowed, though:</p>

<pre><code>{% extends item is defined ? "_item" : [entry.locale ~ "/layout", "_layout"] %}
</code></pre>

<p>Not sure how you apply the concept of <code>{% extends %}</code>, but personally, I very rarely have more than one "layout" template, and that layout template is fairly stark – usually it'll only contain the stuff that <em>all</em> pages across the site should have, i.e. the basic HTML structure (<code>&lt;html&gt;&lt;head&gt;&lt;body&gt;</code>, global header/footer etc) and global CSS/JavaScript). Sure, some designs require more layouts, but usually that's not where the DRY stuff happens – instead, I tend to use "partial" templates (and <a href="http://twig.sensiolabs.org/doc/tags/macro.html" rel="nofollow noreferrer">macros</a>) a lot, to re-use markup.</p>

<p>Assuming your <code>_layout.html</code> contains the basic HTML framework for your site, and that the entry page and an entry inside a listing is basically the same thing (the former just displays more content), you could do something like this to create a template that works for both listings and single entries:</p>

<pre><code>{# Template /news/index.html #}
{% extends '_layout.html' %}
{% block main %}
    {% if entry is defined %}
        {# Single entry #}
        {% include '_partials/entry' %}
    {% else %}
        {# Listing, pull entries and include the entry partial with a "teaser" flag #}
        {% set entries = craft.entries.section('news') %}
        &lt;ul&gt;
            {% for entry in entries %}
                &lt;li&gt;{% include '_partials/entry' with { teaser: true } %}&lt;/li&gt;
            {% endfor %}
        &lt;/ul&gt;
    {% endif %}
{% endblock %}

{# Template /_partials/entry.html #}
{% set isTeaser = teaser is defined and teaser %}
&lt;article class="entry{{ isTeaser ? ' entry--teaser' }}"&gt;
    &lt;h1&gt;{{ entry.title }}&lt;/h1&gt;
    {% if entry.thumbnail|length %}
        &lt;img src="{{ entry.thumbnail.getUrl() }}" /&gt;
    {% endif %}
    &lt;p class="excerpt"&gt;{{ entry.excerpt }}&lt;/p&gt;
    {% if isTeaser %}
        {# Just a teaser – display a "Read more" link #}
        &lt;a href="{{ entry.url }}"&gt;Read more&lt;/a&gt;
    {% else %}
        {# Not a teaser – render the content in full #}
        {{ entry.body }}
    {% endif %}
&lt;/article&gt;
</code></pre>

CC BY-SA 3.0
2016-08-15T08:36:11.353Z
2016-08-15T08:36:11.353Z
2017-05-23T12:38:53.957Z
Mats Mikkel Rummelhoff
<p>Does anyone know a proper way to DRY up an entry template so that it can dynamically become an item listing vs. an entry page? For a (non-working) example:</p>

<p><code>{% if item is defined %}{% else %}{% extends [entry.locale ~ "/layout", "_layout"] %}{% endif %}</code></p>

<p>Not sure why this isn’t working, but it would allow creating one template per section/type and then conditional output based on how you called it in a template, i.e. <code>{% include "entry" with { "item": "small" }</code></p>

<p>Instead of having to create a separate template to output a smaller/truncated version of an item in a list.</p>

<templating>
Dynamically Extend Layout
# Dynamically Extend Layout

(Asked by: username_0 on 2016-08-14)

Does anyone know a proper way to DRY up an entry template so that it can dynamically become an item listing vs. an entry page? For a (non-working) example:

`{% if item is defined %}{% else %}{% extends [entry.locale ~ "/layout", "_layout"] %}{% endif %}`

Not sure why this isn’t working, but it would allow creating one template per section/type and then conditional output based on how you called it in a template, i.e. `{% include "entry" with { "item": "small" }`

Instead of having to create a separate template to output a smaller/truncated version of an item in a list.

**Tags:** templating

---

## 1 answers

### Answer by username_1 on 2016-08-15. Score: 1

Can't be done. In short, a template is either extending another template (i.e. it contains an {% extends %} tag anywhere in the code), or it doesn't. Twig doesn't permit the {% extends %} tag inside an {% if %} statement, which makes "conditional extending" impossible.
Using a ternary operation to conditionally select which template to extend is allowed, though:
{% extends item is defined ? "_item" : [entry.locale ~ "/layout", "_layout"] %}

Not sure how you apply the concept of {% extends %}, but personally, I very rarely have more than one "layout" template, and that layout template is fairly stark – usually it'll only contain the stuff that all pages across the site should have, i.e. the basic HTML structure (, global header/footer etc) and global CSS/JavaScript). Sure, some designs require more layouts, but usually that's not where the DRY stuff happens – instead, I tend to use "partial" templates (and macros) a lot, to re-use markup.
Assuming your _layout.html contains the basic HTML framework for your site, and that the entry page and an entry inside a listing is basically the same thing (the former just displays more content), you could do something like this to create a template that works for both listings and single entries:
{# Template /news/index.html #}
{% extends '_layout.html' %}
{% block main %}
    {% if entry is defined %}
        {# Single entry #}
        {% include '_partials/entry' %}
    {% else %}
        {# Listing, pull entries and include the entry partial with a "teaser" flag #}
        {% set entries = craft.entries.section('news') %}
        
            {% for entry in entries %}
                {% include '_partials/entry' with { teaser: true } %}
            {% endfor %}
        
    {% endif %}
{% endblock %}

{# Template /_partials/entry.html #}
{% set isTeaser = teaser is defined and teaser %}

    {{ entry.title }}
    {% if entry.thumbnail|length %}
        
    {% endif %}
    {{ entry.excerpt }}
    {% if isTeaser %}
        {# Just a teaser – display a "Read more" link #}
        Read more
    {% else %}
        {# Not a teaser – render the content in full #}
        {{ entry.body }}
    {% endif %}


---

