<p>The reason it's not working is that <code>domain.com/people/foo/practices/categoryA</code> is not a match for the Category group's URI settings. Only urls that match <code>people/practices/{slug}</code> are going to have that category variable defined.</p>

<p>And this code:</p>

<pre><code>{% if category is defined %}
    {% set entry = category %}
{% endif %}
</code></pre>

<p>... won't define an entry if there's no category defined.</p>

<p>If your People structure is a flat list (no nested children), you could create a <a href="https://docs.craftcms.com/v3/routing.html#advanced-routing-with-url-rules" rel="nofollow noreferrer">URL rules</a> like this:</p>

<pre><code>'people/&lt;person:{slug}&gt;/practices/&lt;category:{slug}&gt;' =&gt; [
    'template' =&gt; 'test/4'
],
</code></pre>

<p>That would take a URI like <code>domain.com/people/foo/practices/categoryA</code> and use the  <code>people/_practices</code> template and populate variables for <code>person</code> and <code>category</code>.</p>

<pre><code>{{ person }}    {# foo #}
{{ category }}  {# categoryA #}
</code></pre>

<p>Then you could make an category query like this:</p>

<pre><code>{% set cat = craft.categories().group('practices').slug(category).one() %}

{{ cat.title }}
</code></pre>

<p>But personally, I've found it easier to use <strong>query strings</strong> to filter a list instead of URL segments. You could possibly use a URL like this:</p>

<p><code>domain.com/people/foo?practice=categroyA</code></p>

<p>or...</p>

<p><code>domain.com/people/foo/practice?cat=categroyA</code></p>

<p>or even...</p>

<p><code>domain.com/people/practice?person=foo&amp;cat=categroyA</code></p>

<p>Whichever works the most logically for your use case. Then use <code>craft.app.request</code> to pull the "categoryA" string from the URL:</p>

<pre><code>{% set categorySlug = craft.app.request.getQueryParam('cat') ?? null %}

{% if categorySlug %}
  {{ categorySlug }}   {# "categoryA" #}
{% endif %}
</code></pre>

<p>Then use the <code>categorySlug</code> string in an entry or category query:</p>

<pre><code>{% set cat = craft.categories().group('practices').slug(category).one() %}
</code></pre>

<h1>Update</h1>

<p>It's important to note, if you want a variable you set to be available in a layout template (<code>{% extend %}</code> tag), you need to define it outside of a <code>{% block %}</code> tag.</p>

<pre><code>{% extends "_layouts/index" %}

{% set categorySlug = craft.app.request.getQueryParam('cat') ?? null %}

{% block content %}
  Content...
{% endblock %}
</code></pre>

<p>The <code>categorySlug</code> variable should now be available in the <code>_layouts/index</code> template context as well.</p>

<pre><code>&lt;body&gt;
  &lt;div class="language-switcher"&gt;
    {% if categorySlug is defined %}
      Yes it is!
    {% endif %}        
  &lt;/div&gt;

  {% block content %}
  {% endblock %}
&lt;/body&gt;
</code></pre>

CC BY-SA 4.0
2018-09-20T19:48:39.227Z
Thanks much, Alex! I used query strings as you recommended and it worked great. I realized that part of the problem I encountered was that I was setting my `category` and `categorySlug` within my `{% block content %}`. I needed to set these outside my {% block content %} in order for it to have worked with my language switcher, which was in my _layout.html.
user3092
CC BY-SA 4.0
2018-09-22T04:23:31.383Z
Oh, good catch. I'll add a note in about that.
Alex Roper
CC BY-SA 4.0
2018-09-13T23:41:28.573Z
2018-09-22T04:36:23.083Z
2018-09-22T04:36:23.083Z
Alex Roper
<p>I’m having trouble setting up an additional category listing page from the one I have set with the Category URI Format and Template settings in my Category Site Settings. Specifically, I’m having trouble getting it to work on my site which has two locales.</p>

<p>I have one category group called “practices” and one structure section-type called “people.”  I’m trying to create two different pages that each loops through all the entries for a particular category. </p>

<p>In other words, domain.com/people/practices/categoryA and domain.com/people/foo/practices/categoryA would both display all the “people” entries that belong to categoryA.</p>

<p>For my “practices” category group, I have the Category URIs to be people/practices/{slug} and the template to be people/_practices. Everything on this category listing page at domain.com/people/practices/categoryA works as intended.</p>

<p>I can also get the category listing page at domain.com/people/foo/practices/categoryA to work by using the last segment (which would be the category slug) and setting the category object by passing in the category slug like this:</p>

<pre><code>{% set categorySlug = craft.app.request.segments|last %}
{% set category = craft.categories.slug(categorySlug).one() %}
</code></pre>

<p>However, this category listing page is throwing an error when I’m using it with my language switcher code, which uses:</p>

<pre><code>{% if category is defined %}
    {% set entry = category %}
{% endif %}

{% set supportedSites = entry.getSupportedSites %}

&lt;ul&gt;
{% for siteForEntry in supportedSites %}
  {% if siteForEntry | length == 1 %}

    {# if category #}
    {% set site = craft.app.getSites.getSiteById(siteForEntry) %}
    {% set entryForOtherSite = craft.categories.id(entry.id).site(site).one() %}

  {% elseif siteForEntry | length == 2 %}
    {# if standard entry #}
    {% set site = craft.app.getSites.getSiteById(siteForEntry.siteId) %}
    {% set entryForOtherSite = craft.entries.id(entry.id).site(site).one() %}
  {% endif %}

  {% if site.id == entry.siteId %}
      {# This is the current language, mark it as active and don't retrieve its url #}
      &lt;li class="current {{ site.language }}"&gt;{{site.name}}&lt;/li&gt;
  {% else %}
      {# if it's not the current site, get the entry for this site #}
      &lt;li class="{{ site.language }}"&gt;&lt;a href="{{ entryForOtherSite.getUrl() }}"&gt;{{site.name}}&lt;/a&lt;/li&gt;
  {% endif %}

{% endfor %}
&lt;/ul&gt;
</code></pre>

<p>Specifically, I get the “Variable ‘entry’ does not exist” error. I’m not sure why I’m getting this error because I’m setting the “entry” variable with the “category” variable. This works with domain.com/people/practices/categoryA, but it’s not working for the other category listing page. </p>

<pre><code>        {% if category is defined %}
            {% set entry = category %}
        {{ entry.id }}
        {% endif %}
</code></pre>

<p>Not sure what to do. I also set a route so that domain.com/people/foo/practices/{slug} loads the people/_practices template, but it still doesn’t work.</p>

<categories><localization>
Setting up multiple category listing pages on site with multiple locales
# Setting up multiple category listing pages on site with multiple locales

(Asked by: username_0 on 2018-09-12)

I’m having trouble setting up an additional category listing page from the one I have set with the Category URI Format and Template settings in my Category Site Settings. Specifically, I’m having trouble getting it to work on my site which has two locales.
I have one category group called “practices” and one structure section-type called “people.”  I’m trying to create two different pages that each loops through all the entries for a particular category. 
In other words, domain.com/people/practices/categoryA and domain.com/people/foo/practices/categoryA would both display all the “people” entries that belong to categoryA.
For my “practices” category group, I have the Category URIs to be people/practices/{slug} and the template to be people/_practices. Everything on this category listing page at domain.com/people/practices/categoryA works as intended.
I can also get the category listing page at domain.com/people/foo/practices/categoryA to work by using the last segment (which would be the category slug) and setting the category object by passing in the category slug like this:
{% set categorySlug = craft.app.request.segments|last %}
{% set category = craft.categories.slug(categorySlug).one() %}

However, this category listing page is throwing an error when I’m using it with my language switcher code, which uses:
{% if category is defined %}
    {% set entry = category %}
{% endif %}

{% set supportedSites = entry.getSupportedSites %}


{% for siteForEntry in supportedSites %}
  {% if siteForEntry | length == 1 %}

    {# if category #}
    {% set site = craft.app.getSites.getSiteById(siteForEntry) %}
    {% set entryForOtherSite = craft.categories.id(entry.id).site(site).one() %}

  {% elseif siteForEntry | length == 2 %}
    {# if standard entry #}
    {% set site = craft.app.getSites.getSiteById(siteForEntry.siteId) %}
    {% set entryForOtherSite = craft.entries.id(entry.id).site(site).one() %}
  {% endif %}

  {% if site.id == entry.siteId %}
      {# This is the current language, mark it as active and don't retrieve its url #}
      {{site.name}}
  {% else %}
      {# if it's not the current site, get the entry for this site #}
      {{site.name}}
  {% endif %}

{% endfor %}


Specifically, I get the “Variable ‘entry’ does not exist” error. I’m not sure why I’m getting this error because I’m setting the “entry” variable with the “category” variable. This works with domain.com/people/practices/categoryA, but it’s not working for the other category listing page. 
        {% if category is defined %}
            {% set entry = category %}
        {{ entry.id }}
        {% endif %}

Not sure what to do. I also set a route so that domain.com/people/foo/practices/{slug} loads the people/_practices template, but it still doesn’t work.

**Tags:** categories, localization

---

## 1 answers

### Answer by username_1 on 2018-09-13. Score: 1

The reason it's not working is that domain.com/people/foo/practices/categoryA is not a match for the Category group's URI settings. Only urls that match people/practices/{slug} are going to have that category variable defined.
And this code:
{% if category is defined %}
    {% set entry = category %}
{% endif %}

... won't define an entry if there's no category defined.
If your People structure is a flat list (no nested children), you could create a URL rules like this:
'people//practices/' => [
    'template' => 'test/4'
],

That would take a URI like domain.com/people/foo/practices/categoryA and use the  people/_practices template and populate variables for person and category.
{{ person }}    {# foo #}
{{ category }}  {# categoryA #}

Then you could make an category query like this:
{% set cat = craft.categories().group('practices').slug(category).one() %}

{{ cat.title }}

But personally, I've found it easier to use query strings to filter a list instead of URL segments. You could possibly use a URL like this:
domain.com/people/foo?practice=categroyA
or...
domain.com/people/foo/practice?cat=categroyA
or even...
domain.com/people/practice?person=foo&cat=categroyA
Whichever works the most logically for your use case. Then use craft.app.request to pull the "categoryA" string from the URL:
{% set categorySlug = craft.app.request.getQueryParam('cat') ?? null %}

{% if categorySlug %}
  {{ categorySlug }}   {# "categoryA" #}
{% endif %}

Then use the categorySlug string in an entry or category query:
{% set cat = craft.categories().group('practices').slug(category).one() %}

Update
It's important to note, if you want a variable you set to be available in a layout template ({% extend %} tag), you need to define it outside of a {% block %} tag.
{% extends "_layouts/index" %}

{% set categorySlug = craft.app.request.getQueryParam('cat') ?? null %}

{% block content %}
  Content...
{% endblock %}

The categorySlug variable should now be available in the _layouts/index template context as well.

  
    {% if categorySlug is defined %}
      Yes it is!
    {% endif %}        
  

  {% block content %}
  {% endblock %}

> **Comments:**
> **username_0**: Thanks much, Alex! I used query strings as you recommended and it worked great. I realized that part of the problem I encountered was that I was setting my `category` and `categorySlug` within my `{% block content %}`. I needed to set these outside my {% block content %} in order for it to have worked with my language switcher, which was in my _layout.html.  
> **username_1**: Oh, good catch. I'll add a note in about that.  

---

