23

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?

0

3 Answers 3

44

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'
] %}
5
  • 3
    That's very clever! Per the Twig docs, "The first template that exists will be used as a parent". twig.sensiolabs.org/doc/tags/extends.html#dynamic-inheritance
    – Lindsey D
    Commented Jun 12, 2014 at 19:46
  • 2
    In my opinion, this should be marked as the best answer. You may also want to share this "recipe" on craftcookbook.net
    – Lindsey D
    Commented Jun 12, 2014 at 20:23
  • 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? Commented Jun 30, 2014 at 17:58
  • no, not in the scenario above
    – Ben Croker
    Commented Dec 17, 2014 at 19:26
  • 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' ] %} Commented Feb 24, 2017 at 14:20
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.

1
  • 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
    Commented Jun 12, 2014 at 20:02
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.