How can I use tag slugs in URLs? This question is a summary of my working with tags yesterday, I'm posting my findings to SE so other people can benefit.



For the purposes of this question, I'm going to be using a tag with the title 'Two Words'.

I'm trying to add a tags listing and filtering system to a blog. As tags don't have a 'slug' property, I've been having issues using them in URLs. If I use the following links:

{% for tag in tags %}
    &lt;a href="/news/tags/{{ tag.title }}"&gt;{{ tag.title }}&lt;/a&gt;
{% endfor %}


Then you get unfriendly urls such as http://craft.dev/news/tags/Two%20Words. If I use :

{% set tag = craft.tags.search(craft.request.getSegment(3)) %}
{% for entry in craft.entries.relatedTo(tag) %}


Then I get a list of articles that may contain the term "two words", but aren't actually tagged with Two Words.

I want to list articles related to the tag in the URL, so how can I pull the specific tag from the url, making sure it stays 'url-friendly'?
The key to this is to use the |kebab filter and the relatedTo params.

Listing:

{% for tag in relatedTags %}
    &lt;li&gt;&lt;a href="/news/tags/{{ tag.title|kebab }}"&gt;{{ tag.title }}&lt;/a&gt;&lt;/li&gt;
{% endfor %}


Fetch related articles

{% set tag = craft.tags.search(craft.request.getSegment(4)) %}

{% for entry in craft.entries.relatedTo({ targetElement: tag[0], field: tagField }) %}


The tag[0] is necessary, as {{ craft.tags.search() }} will return an array (even if there's only one tag returned).

This finds entries that are specifically related to Two Words (a tag object, pulled from the URL), and searches in the tagField specified.

The alternative to the above is to use {{ tag.id }} and {{ craft.tags.id() }}, but that isn't URL/SEO friendly.