Setting up multiple category listing pages on site with multiple locales 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 %}

&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;


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.
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/&lt;person:{slug}&gt;/practices/&lt;category:{slug}&gt;' =&gt; [
    'template' =&gt; '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&amp;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.

&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;