Take the 2-minute tour ×
Craft CMS Stack Exchange is a question and answer site for administrators, end users, developers and designers for Craft CMS. It's 100% free, no registration required.

Just wondering how people approach setting a class of current in their navigation. Is there anything in Craft or Twig where you can set a conditional to check if a page is the current page. Or do you just need to set classes/ids on the body tag based on the segment?

Any ideas appreciated, Gareth

share|improve this question

7 Answers 7

up vote 5 down vote accepted

Tip: To keep it short and reusable I would recommend that you wrap your preferred "check-method" in a Twig macro, I like Anna's version the most:

_macros.html:

{% macro is_active(segment) %}{% if craft.request.firstSegment == segment %}active{% endif %}{% endmacro %}

layout.html:

{% import "_macros.html" as macros %}

<a href="{{ url('news') }}" class="{{ macros.is_active('news') }}">News</a>
<a href="{{ url('blog') }}" class="{{ macros.is_active('blog') }}">Blog</a>
share|improve this answer
    
Wow great addition, thank you Victor. –  Gareth Redfern Jun 28 at 18:20

Assuming you use a structure called pages to create your navigation and the entry variable represents the currently viewed entry, you can output your navigation and active state as follows:

<ul>
{% nav page in craft.entries.section('pages') %}
    <li class="{{ page.id == entry.id ? 'active' }}">
        {{ page.link }}
        {% ifchildren %}
            <ul>
                {% children %}
            </ul>
        {% endifchildren %}
    </li>
{% endnav %}
</ul>

See the nav tag for more details.

If, instead of a structure, you are using a channel called pages for the navigation then the nav tag method above will still work but the following code is leaner and simpler to understand:

<ul>
{% for page in craft.entries.section('pages') %}
    <li class="{{ page.id == entry.id ? 'active' }}">
        {{ page.link }}
    </li>
{% endfor %}
</ul>
share|improve this answer
    
Thanks Ben, I hadn't even looked into the nav tag, this only works for a structured section though, right? Still very useful, thank you. –  Gareth Redfern Jun 28 at 15:03
    
it should work for a channel too, i updated my answer above with code for a channel though. –  Ben Croker Jun 30 at 9:01

Barrel Strength also have a URL segment based plugin called Sprout Active, with docs/examples here.

share|improve this answer
    
Thanks Matt, I'll check it out :) –  Gareth Redfern Jun 28 at 18:13

In your template you can set a var in twig:

{% set active = 'blog' %}

And then in your navigation you can run an if statement to see what the var is

<nav>
    <a {% if active = 'homepage' %}class="active"{% endif %}> Home </a>
    <a {% if active = 'blog' %} class="active"{% endif %}> Blog </a>
</nav>
share|improve this answer
    
Thank you Rob, this looks as if it works great until you re-use a template. Then I guess you would need to use a craft.request to check the segment variable? –  Gareth Redfern Jun 28 at 15:07
    
Yeah you are probably right. For simple sites using Craft Personal you can get away with my above answer. However if you're doing something much larger, you might want to check out @Anna_MediaGirl's answer. –  Rob Erskine Jun 30 at 14:36

craft.request is useful for setting an "active" class based on URL segments.

If your URL was: domain.com/sale/products/shirts

You could write conditionals like the following to target each segment:

{% if craft.request.firstSegment == "sale" %}class="active"{% endif %}
{% if craft.request.segment(2) == "products" %}class="active"{% endif %}
{% if craft.request.lastSegment == "shirts" %}class="active"{% endif %}
share|improve this answer
1  
Thanks Anna, I was thinking down this route, great minds :) thank you for your answer - have you seen Victor's suggestion using a macro with your code, looks like a nice we to keep things DRY. –  Gareth Redfern Jun 28 at 18:18

Here's yet another way you can do it (in some circumstances) and it's nice and DRY:

{% if craft.request.getPath() ==  entry.uri %}
share|improve this answer

I add a variable in my "_entry" template.

Here's a basic example:

{% extends "_layout" %}

{% set bodyClass = 'myPageType' %}

{% block content %}
<!-- entry HTML here -->
{% endblock %}

Then in my _layout template, it begins like this:

<!doctype html>
<html class="{% if bodyClass is defined %}{{ bodyClass }}{% endif %}">
<!-- the rest of the template follows -->

Does something like that work for you?

share|improve this answer
    
Hey, John there are a few different options now, this page has become a great resource, thank you for your answer. –  Gareth Redfern Jun 28 at 18:20

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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