Dynamically Extend Layout 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.
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 (&lt;html&gt;&lt;head&gt;&lt;body&gt;, 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') %}
        &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;