Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-05-16T13:45:09.567Z
Answers.Text: 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).
Answers.UserDisplayName: Jonathan Schofield
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-05-10T12:14:19.163Z
Answers.LastActivityDate: 2018-05-11T08:42:50.970Z
Answers.LastEditDate: 2018-05-11T08:42:50.970Z
Answers.UserDisplayName: Piaras Hoban
Body: <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>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2018-05-08T00:37:19.307Z
Comments.Text: 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.
Comments.UserDisplayName: Jonathan Schofield
Tags: <templating><segments>
Title: Template logic to address a third URL segment
ThreadText: # 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:
  
  ---
  
  1. 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
  
  ---
  
  2. Setting a **route** to a different template:
  
  `stories/{slug}/{*}`
  
  …is processed by:
  
  `stories/_extract`
  
  …in which, as a basic test I have:
  
  ```
  {% block meta %}
      <title>{{ entry.title }}</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 %}
          <title>{{ entry.title }}</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/<slug:\w+>/?<option:\w+>?' => ['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 %}
              <h1>Entry title is: {{ entry.title }}</h1>
      {% endif %}
  
      <h2>Slug is: {{ slug }} </h2>
  
      {% if option is defined %}
              <h3>Option is: {{ option }}</h3>
      {% 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, username_1. 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).  
  
  ---
  
  