<p>I would suggest you look into using Craft's Advanced Routing functionality to accomplish this.</p>

<p>For instance, add the following to your <code>config/routes.php</code>:</p>

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

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

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

<pre><code>    {% 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 %}
</code></pre>

<p>I'd recommend reading the docs on Advanced routing as it's quite a powerful feature: <a href="https://docs.craftcms.com/v3/routing.html#advanced-routing" rel="nofollow noreferrer">https://docs.craftcms.com/v3/routing.html#advanced-routing</a></p>

CC BY-SA 4.0
2018-05-16T13:45:09.567Z
Belated thanks for this, Piaras. With Brad @ P&T's help on a support ticket, I'd already arrived at my fundamental mistake which was setting entry with .all() instead of .one(), and then everything fell into place. I just hadn't properly grasped when to use those methods, but the newly revised v3 docs are [a lot clearer](https://docs.craftcms.com/v3/element-queries.html#all).
Jonathan Schofield
CC BY-SA 4.0
2018-05-10T12:14:19.163Z
2018-05-11T08:42:50.970Z
2018-05-11T08:42:50.970Z
Piaras Hoban
<p>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.)</p>

<p>I have a url of the form: </p>

<p><code>stories/{slug}</code></p>

<p>served by a template: </p>

<p><code>stories/_entry</code></p>

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

<p>But I also want to address urls of the form:</p>

<p><code>stories/{slug}/{variable}</code></p>

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

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

<p>I have tried 2 approaches:</p>

<hr>

<ol>
<li>Getting segment 3 and then using it in a <strong>conditional</strong> inside of <code>stories/_entry</code>:</li>
</ol>

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

<p>…but when seg3 is not empty Craft says: </p>

<blockquote>
  <p>Template not found</p>
</blockquote>

<hr>

<ol start="2">
<li>Setting a <strong>route</strong> to a different template:</li>
</ol>

<p><code>stories/{slug}/{*}</code></p>

<p>…is processed by:</p>

<p><code>stories/_extract</code></p>

<p>…in which, as a basic test I have:</p>

<pre><code>{% block meta %}
    &lt;title&gt;{{ entry.title }}&lt;/title&gt;
{% endblock %}
</code></pre>

<p>…but Craft then reports a Twig runtime error, saying: </p>

<blockquote>
  <p>Variable "entry" does not exist</p>
</blockquote>

<p>So I tried using:</p>

<pre><code>{% 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 %}
</code></pre>

<p>…but that makes no difference.</p>

<hr>

<p>Is my approach 2 definition of <code>entry</code> wrong?</p>

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

<p>I'm obviously missing something fundamental here. Any pointers much appreciated.</p>

CC BY-SA 4.0
2018-05-08T00:37:19.307Z
I note that approach 2 is exactly what is advocated at https://craftcms.stackexchange.com/a/4675/3507. And yet, for me, it doesn't work. Perhaps something is different under Craft 3 I haven't Twigged (groan) to yet.
Jonathan Schofield
<templating><segments>
Template logic to address a third URL segment
# Template logic to address a third URL segment

(Asked by: username_0 on 2018-05-07)

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 %}
    {{ entry.title }}
{% 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 %}
        {{ entry.title }}
    {% 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.

**Tags:** templating, segments
> **Comments:**
> **username_0**: I note that approach 2 is exactly what is advocated at https://craftcms.stackexchange.com/a/4675/3507. And yet, for me, it doesn't work. Perhaps something is different under Craft 3 I haven't Twigged (groan) to yet.  

---

## 1 answers

### Answer by username_1 on 2018-05-10. Score: 4

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//??' => ['template' => '_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 %}
            Entry title is: {{ entry.title }}
    {% endif %}

    Slug is: {{ slug }} 

    {% if option is defined %}
            Option is: {{ option }}
    {% 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

> **Comments:**
> **username_0**: Belated thanks for this, Piaras. With Brad @ P&T's help on a support ticket, I'd already arrived at my fundamental mistake which was setting entry with .all() instead of .one(), and then everything fell into place. I just hadn't properly grasped when to use those methods, but the newly revised v3 docs are [a lot clearer](https://docs.craftcms.com/v3/element-queries.html#all).  

---

