Template logic to address a third URL segment I'm using Craft 3, and I'm struggling to make sense of how to address the following. (I've not had need to venture into a third URL segment before.)

I have a url of the form: 

stories/{slug}

served by a template: 

stories/_entry

I'm aware that the 'entry' variable gets set automatically. So far so basic.

But I also want to address urls of the form:

stories/{slug}/{variable}

…where variable is used to fetch content from a specific Matrix row in the entry that matches slug.

It is important that variable forms a third segment addressable as its own page, and not just a URL query parameter.

I have tried 2 approaches:




Getting segment 3 and then using it in a conditional inside of stories/_entry:


{% set seg3 = craft.app.request.getSegment(3) %}
{% if seg3|length %}
    {% include 'partials/extract' %}
{% else %}
    {% include 'partials/story' %}
{% endif %}

…but when seg3 is not empty Craft says: 


  Template not found





Setting a route to a different template:


stories/{slug}/{*}

…is processed by:

stories/_extract

…in which, as a basic test I have:

{% block meta %}
    &lt;title&gt;{{ entry.title }}&lt;/title&gt;
{% endblock %}


…but Craft then reports a Twig runtime error, saying: 


  Variable "entry" does not exist


So I tried using:

{% set seg2 = craft.app.request.getSegment(2) %}
{% for entry in craft.entries.section('stories').slug(seg2).all() %}
    {% block meta %}
        &lt;title&gt;{{ entry.title }}&lt;/title&gt;
    {% endblock %}
{% endfor %}


…but that makes no difference.



Is my approach 2 definition of entry wrong?

Why does a non-empty value in segment 3 cause approach 1 to fail?

I'm obviously missing something fundamental here. Any pointers much appreciated.
I would suggest you look into using Craft's Advanced Routing functionality to accomplish this.

For instance, add the following to your config/routes.php:

'stories/&lt;slug:\w+&gt;/?&lt;option:\w+&gt;?' =&gt; ['template' =&gt; '_extract'],


This will then populate the _extract template with the twig variable {{ slug }} and also the {{ option }} variable, if it exists.

Then in your twig template you can grab the entry and check for the existence of the option variable thus:

    {% set entry = craft.entries.section('stories').slug(slug).one() %}

    {% if entry %}
            &lt;h1&gt;Entry title is: {{ entry.title }}&lt;/h1&gt;
    {% endif %}

    &lt;h2&gt;Slug is: {{ slug }} &lt;/h2&gt;

    {% if option is defined %}
            &lt;h3&gt;Option is: {{ option }}&lt;/h3&gt;
    {% endif %}


I'd recommend reading the docs on Advanced routing as it's quite a powerful feature: https://docs.craftcms.com/v3/routing.html#advanced-routing