How can I route a specific entry in a structure section to its own template?

21

18

While setting up a site recently I wanted to route a specific entry in a structure section to its own custom template. Using a dynamic route sounded like the right option until I remembered that it wouldn't work due to Craft's routing order (matched entry uri comes before matched template).

I considered adding a conditional redirect to the structure's generic template but this feels a bit dirty. Does anyone have a better solution of how to make this work?

Ben Croker

Posted 2014-06-12T19:07:56.340

Reputation: 3 178

Answers

40

The cleanest way I have found to achieve this is to create a generic template for the structure as well as a custom template for each entry that needs one, ensuring that its path matches the entry's uri.

I then put this single line of code in the structure's selected template and it works beautifully:

{% extends [entry.uri, '_generic'] %}

This should work as well:

{% include [entry.uri, '_generic'] %}

If the entry's uri exists as a template route then it will be rendered, otherwise the generic template will be.

UPDATE:

I recently extended this on a site to allow for unique custom pages, custom entry type pages and a fallback generic page:

{% extends [
    '_custom/' ~ entry.slug,
    '_entrytypes/' ~ entry.type,
    '_generic'
] %}

Ben Croker

Posted 2014-06-12T19:07:56.340

Reputation: 3 178

2

In my opinion, this should be marked as the best answer. You may also want to share this "recipe" on http://craftcookbook.net/

– Lindsey D – 2014-06-12T20:23:15.837

Im having a bit of a problem managing this method where the entry.uri file needs to extend blocks in the main file. Any ideas? – Steve Adams – 2014-06-30T17:58:46.680

If your entries are in Structure, and some pages need to use different template, you can use this code in your 'main' template defined in section settings. {% extends [ craft.request.path, '_generic' ] %} – Yuri Salimovskiy – 2017-02-24T14:20:22.600

no, not in the scenario above – Ben Croker – 2014-12-17T19:26:29.103

3

That's very clever! Per the Twig docs, "The first template that exists will be used as a parent". http://twig.sensiolabs.org/doc/tags/extends.html#dynamic-inheritance

– Lindsey D – 2014-06-12T19:46:03.940

5

Currently, the conditional redirect is the best way. You can use it to load a template dynamically in the structure's generic _entry template using the include tag.

My suggestion would be to add a lightswitch field that tells the entry to load a custom template. Then in the _entry template do something like this:

{% if entry.customTemplate %}
    {% include "section/_" ~ entry.slug %}
{% else %}
    {% include "section/_generic" %}
{% endif %}

This is the same basic idea used in Pixel & Tonic's help page on using different templates for different entry types.

Bryan Redeagle

Posted 2014-06-12T19:07:56.340

Reputation: 3 867

thanks bryan, this is close to what i did except that i managed to drop the conditional and use an array in the include in its place. – Ben Croker – 2014-06-12T20:02:04.880

1

I think you are on the right track. Call the generic template _route.html, and have it do nothing but {%extends ...%} to route to the template you want.

Marion Newlevant

Posted 2014-06-12T19:07:56.340

Reputation: 10 149