I've browsed the questions and answers here and i can't find anything that works for what i'm trying to do!

I am using this as the main menu of my site (so it is in _layout.html)

{% nav category in craft.categories.group('artCats') %}
{% set entryCount = craft.entries.relatedTo(category).total()
  <li><a href="{{ category.url }}"><span>{{ category.title }}</span>{% if category.level == 2 %}<span class="postnum">({{ entryCount }})</span>{% endif %}</a>
  {% ifchildren %}
      {% children %}
  {% endifchildren %}
{% endnav %}

It's a drop down menu that shows how many posts are in each sub category. All works nicely!

However, no matter what i try, i can't seem to dynamically assign a class to the current page. I think i'm misunderstanding in general how this is done in Craft.

I see a lot of solutions that are basically saying "if url segment is "fishcake" then add my class" but to me, that's not dynamic at all! Dynamic would be if i add a new sub-category, the menu will add my desired class to that menu item if i visit, without me having to add a new if statement in the Twig code.

Am i able to do something like "if the category.url of this link matches the current url, do this" ?

1 Answer 1


You can get the current Category Model via the pre-populated category variable on all of your category pages. (→ see Routing type no. 4)

As you probably know, entry pages come with entry pre-populated. To get all the Category Models that are related to an entry page with a Categories Field make a craft.categories call using relatedTo(entry) as a parameter.

Save the Category Model / -Models to a var outside your nav loop, so you don't have to make those requests multiple times. And make sure to save the one Category Model on category pages as an array [myCategoryModel], so you always end up with your variable being of the same type.

Within you nav loop you can now check, if the Category Model of your current loop iteration is within your saved array using the in containment operator.

{# Is this an entry page with a category field? #}
{% if entry is defined %}
    {% set currentCategoryIds = craft.categories.relatedTo(entry).ids() %}
{# Is this a category page? #}
{% elseif category is defined %}
    {% set currentCategoryIds = [category.id] %}
{# None of both? Set an empty array. #}
{% else %}
    {% set currentCategoryIds = [] %}
{% endif %}

{% nav cat in craft.categories.group('artCats') %}

    {% set class = cat.id in currentCategoryIds ? 'current' : '' %}
    {% set entryCount = craft.entries.relatedTo(cat).total() %}

    <li><a href="{{ cat.url }}" class="{{ class }}">{{ cat.title }} ({{ entryCount }})</a></li>

{% endnav %}
  • If i do that, i get the following error: Variable "entry" does not exist. It highlights that very first line as where the error happens. The site homepage doesn't throw that error, it only happens when i am in a category page like sitename.com/categoryname
    – Dan Owen
    Feb 16, 2015 at 16:43
  • @DanOwen Ahh sorry, I made the code to only work for entry pages (single, channel or structure entries with a categories field). Will try to change this...
    – carlcs
    Feb 16, 2015 at 16:54
  • @DanOwen I'm actually not sure if a category page automatically comes with a Category Model pre-assigned to the var category. If it does, the updated code could work ;)
    – carlcs
    Feb 16, 2015 at 17:03
  • 1
    @carlcs It does. I was wondering the same and just checked. Feb 16, 2015 at 17:20
  • @carlcs Sounds good! BUT! It still throws that error for me on category list pages (it flag up the very first {% if entry %} as the error). That is, if a user clicks a category name, it lists all of the entries in that category (so im not in a page with a category field)
    – Dan Owen
    Feb 16, 2015 at 17:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.