<p>There is <a href="http://buildwithcraft.com/help/tag-urls" rel="nofollow">a detailed help article dedicated to that</a> in the help section of the Craft website.</p>

<p>In short</p>

<ul>
<li>create a route</li>
<li>get all entries related to the tag</li>
<li>use <code>{{ tag.name | url_encode }}</code> to create the URL pointing to the tag page</li>
</ul>

CC BY-SA 3.0
2014-07-08T18:45:48.197Z
2014-07-08T18:45:48.197Z
Jérôme Coupé
<p>I setup a route, in my case "news/tag/[tag]" with a template <strong>news/_tag</strong>. Then in the template I find the tag:</p>

<pre><code>{% set actualTag = craft.tags.name(tag).first() %}
{% if not actualTag %}{% exit 404 %}{% endif %}
</code></pre>

<p>and get the entries related to the tag (could additionally restrict this by section):</p>

<pre><code>{% set relevantEntries = craft.entries
  .relatedTo({
    targetElement: actualTag,
    field: 'tags'
  })
%}
</code></pre>

<p>[edited to add:]
To get the list of tags with links to the tag pages (twig <a href="http://twig.sensiolabs.org/doc/filters/url_encode.html" rel="nofollow">url_encode</a> to translate tag name to url):</p>

<pre><code>{% for tag in craft.tags.relatedTo({
    sourceElement: entries,
    field: 'tags'
  }).order('name')
%}
  {% set tagUrl = '/news/tag/'~(tag.name|url_encode) %}
  &lt;a href="{{tagUrl}}"&gt;{{tag.name}}&lt;/a&gt;
{% endfor %}
</code></pre>

CC BY-SA 3.0
2014-07-08T17:25:56.950Z
Do you use the tag as is in the URL or do you "slugify" it or create a secondary field for the "slug" field?
Ryan Shrum
CC BY-SA 3.0
2014-07-08T17:28:05.277Z
I use the tag as is. My theory is that is what tags are designed for.
Marion Newlevant
CC BY-SA 3.0
2014-07-08T17:28:53.160Z
So you use it with spaces if applies? i.e. "this is my tag" Which would render ".com/news/tag/this is my tag"
Ryan Shrum
CC BY-SA 3.0
2014-07-08T17:31:31.343Z
craft turns that into "this+is+my+tag", and I use that
Marion Newlevant
CC BY-SA 3.0
2014-07-08T17:55:14.967Z
Actually, I pass it through url_encode, and use that:{{tag.name|url_encode}}. Editing my original answer to include that...
Marion Newlevant
CC BY-SA 3.0
2014-07-08T18:02:02.060Z
For your route, does `news/tag/[tag]` work or do you use the wildcard and/or slug? In place of `[tag]` - `new/tag/*` or `new/tag/slug`
Ryan Shrum
CC BY-SA 3.0
2014-07-08T16:28:18.977Z
2014-07-08T17:59:29.937Z
2014-07-08T17:59:29.937Z
Marion Newlevant
<p>Not sure if this is the best way to go, but thus far I've used a custom route (in Settings->Routes) to setup tag listing/landing pages. Something like tags/* so the wildcard catches the tag slug. </p>

<pre><code>{% set tagId = "" %} {# set the initial tagID variable outside of your loop to access it later in the template #}

{% if craft.request.getSegment(1) == "tags" %} {# if you're on the tag listing template #}
    {% set tags = craft.tags.find() %} {# get all tags in the system #}
    {% for tag in tags %}
        {% set tagUrl = tag.name|lower|replace({' ': '-'}) %} {# do the same string manipulation that you did to create the slug that links to this page #}
        {% if (tagUrl == craft.request.getSegment(2)) %} {# grab the tag that matches your URL #}
            {% set tagId = tag.id %}
        {% endif %}
    {% endfor %}
{% endif %}
</code></pre>

<p>Then, grab entries that are related to this tag:</p>

<pre><code>{% set tag = craft.tags.id(tagId) %}
{% set entries = craft.entries.section('blog').relatedTo(tag).find() %}
</code></pre>

CC BY-SA 3.0
2014-07-08T16:11:26.913Z
2014-07-08T16:11:26.913Z
jpea
<p>Here's a really DRY way to do it.</p>

<p>Setup a route, something like "news/tags/(tag)" to load the "news/index" template (the same one used for listing all entries).</p>

<p>In the "news/index" template:</p>

<pre class="lang-twig prettyprint-override"><code>{# If there is a tag token in the URL, set a filtered variable. #}
{% if tag is defined %}

    &lt;h2&gt;Tag: {{ tag }}&lt;/h2&gt;

    {% set tag = craft.tags.name(tag).first() %}

    {% set entriesToShow = craft.entries.section('news').relatedTo(tag) %}

{% else %} {# No tag token in URL, assume unfiltered overview page. #}

    {% set entriesToShow = craft.entries.section('news') %}

{% endif %}

{# the entry loop for both filtered and unfiltered entries #}
{% for entry in entriesToShow %} 
    {# display entry #}
{% endfor %}
</code></pre>

<p>When templating tag links to this system use:</p>

<pre class="lang-twig prettyprint-override"><code>{{ siteUrl }}news/tag/{{ tag.name|url_encode }}
</code></pre>

<p>This method allows you to reuse your entry loop and you don't even need a "tags" template. I can also be expanded to filter by categories as well without needing another template.</p>

CC BY-SA 3.0
2014-07-08T19:14:43.453Z
2014-07-09T02:27:43.523Z
2014-07-09T02:27:43.523Z
Simon Kuran
<p>It doesn't appear that tags are handled the same way as categories in the sense that categories have a slug (which results to a URI). I'd like to use tags to link to a "tag" page, similar to a category page, but "Really Cool Tag Name" doesn't work/look right as part of a URL. I've used the Slugify plugin to turn the tag in to a slug, however, I'm not sure the best approach to return the relationship of that tag as that slug is not related to the tag at all. Would the best practice be to add an additional slug field to the tag group? Then I'd be able to make that relationship. Thoughts?</p>

<entries><tags>
Looking to use a tag slug/URI and loop through entries of that tag
# Looking to use a tag slug/URI and loop through entries of that tag

(Asked by: username_0 on 2014-07-08)

It doesn't appear that tags are handled the same way as categories in the sense that categories have a slug (which results to a URI). I'd like to use tags to link to a "tag" page, similar to a category page, but "Really Cool Tag Name" doesn't work/look right as part of a URL. I've used the Slugify plugin to turn the tag in to a slug, however, I'm not sure the best approach to return the relationship of that tag as that slug is not related to the tag at all. Would the best practice be to add an additional slug field to the tag group? Then I'd be able to make that relationship. Thoughts?

**Tags:** entries, tags


---

## 4 answers

### Answer by username_4 on 2014-07-08. Score: 6 | Accepted answer

Here's a really DRY way to do it.
Setup a route, something like "news/tags/(tag)" to load the "news/index" template (the same one used for listing all entries).
In the "news/index" template:
{# If there is a tag token in the URL, set a filtered variable. #}
{% if tag is defined %}

    Tag: {{ tag }}

    {% set tag = craft.tags.name(tag).first() %}

    {% set entriesToShow = craft.entries.section('news').relatedTo(tag) %}

{% else %} {# No tag token in URL, assume unfiltered overview page. #}

    {% set entriesToShow = craft.entries.section('news') %}

{% endif %}

{# the entry loop for both filtered and unfiltered entries #}
{% for entry in entriesToShow %} 
    {# display entry #}
{% endfor %}

When templating tag links to this system use:
{{ siteUrl }}news/tag/{{ tag.name|url_encode }}

This method allows you to reuse your entry loop and you don't even need a "tags" template. I can also be expanded to filter by categories as well without needing another template.


---

### Answer by username_1 on 2014-07-08. Score: 3

There is [a detailed help article dedicated to that](http://buildwithcraft.com/help/tag-urls) in the help section of the Craft website.

In short

* create a route
* get all entries related to the tag
* use `{{ tag.name | url_encode }}` to create the URL pointing to the tag page


---

### Answer by username_2 on 2014-07-08. Score: 2

I setup a route, in my case "news/tag/[tag]" with a template news/_tag. Then in the template I find the tag:
{% set actualTag = craft.tags.name(tag).first() %}
{% if not actualTag %}{% exit 404 %}{% endif %}

and get the entries related to the tag (could additionally restrict this by section):
{% set relevantEntries = craft.entries
  .relatedTo({
    targetElement: actualTag,
    field: 'tags'
  })
%}

[edited to add:]
To get the list of tags with links to the tag pages (twig url_encode to translate tag name to url):
{% for tag in craft.tags.relatedTo({
    sourceElement: entries,
    field: 'tags'
  }).order('name')
%}
  {% set tagUrl = '/news/tag/'~(tag.name|url_encode) %}
  {{tag.name}}
{% endfor %}

> **Comments:**
> **username_0**: Do you use the tag as is in the URL or do you "slugify" it or create a secondary field for the "slug" field?  
> **username_2**: I use the tag as is. My theory is that is what tags are designed for.  
> **username_0**: So you use it with spaces if applies? i.e. "this is my tag" Which would render ".com/news/tag/this is my tag"  
> **username_2**: craft turns that into "this+is+my+tag", and I use that  
> **username_2**: Actually, I pass it through url_encode, and use that:{{tag.name|url_encode}}. Editing my original answer to include that...  
> **username_0**: For your route, does `news/tag/[tag]` work or do you use the wildcard and/or slug? In place of `[tag]` - `new/tag/*` or `new/tag/slug`  

---

### Answer by username_3 on 2014-07-08. Score: 1

Not sure if this is the best way to go, but thus far I've used a custom route (in Settings->Routes) to setup tag listing/landing pages. Something like tags/* so the wildcard catches the tag slug. 
{% set tagId = "" %} {# set the initial tagID variable outside of your loop to access it later in the template #}

{% if craft.request.getSegment(1) == "tags" %} {# if you're on the tag listing template #}
    {% set tags = craft.tags.find() %} {# get all tags in the system #}
    {% for tag in tags %}
        {% set tagUrl = tag.name|lower|replace({' ': '-'}) %} {# do the same string manipulation that you did to create the slug that links to this page #}
        {% if (tagUrl == craft.request.getSegment(2)) %} {# grab the tag that matches your URL #}
            {% set tagId = tag.id %}
        {% endif %}
    {% endfor %}
{% endif %}

Then, grab entries that are related to this tag:
{% set tag = craft.tags.id(tagId) %}
{% set entries = craft.entries.section('blog').relatedTo(tag).find() %}


---

