4

I have a navigation like this:

{% set navi = craft.entries.id('2, 4, 5, 6' ).order('id asc') %} 
<nav>
  <ul>
    {% for entry in navi %}
      <li><a href="{{ entry.url }}" {% if entry.url == craft.request.geturl %}class="active"{% endif %}>{{ entry.naviTitel }}</a></li>
    {% endfor %}
  </ul>
</nav>

This results in something like:

  • Home
  • Projects
  • About
  • Contact

Now under Projects (Wich is a Single entry) are entry pages like this:

  • url/projects/project_entry_1
  • url/projects/project_entry_2

Now what I'm trying to achieve is that when viewing a project_entry, the nav link "Project" should have the class active which is not the case right now. Is this somehow possible with this navi markup or do I have to write something like this.

I taught about writing a conditional {% if url_segment 2 == project %} but that doesn't work because this would give all links the class active and since I have a multi-language installation segment_2 is not always the single slug.

What is the prettiest way to achieve this?

Thank you.

2

You need to get all possible translations of your entry slug to do a thorough comparison.

This is only possible with additional DB queries (ElementCriteriaModels) for each of your navigation items and each of your installed locales, if you don't want to hardcode the values into your template.

Because your navigation probably doesn't change that often, I'd do it anyways and simply wrap the whole navigation in {% cache %} tags with a really long invalidation time (it does get updated if anything is changed within the tags though!).

{% cache for 3 years %}
{% for naviItem in navi %}

    {# Get the relevant URL segment #}
    {% set segment = craft.request.segment(1) %}

    {# Get all possible translations of the entry slug #}
    {% set enSlug = craft.entries.id(naviItem.id).locale('en').first().uri %}
    {% set frSlug = craft.entries.id(naviItem.id).locale('fr').first().uri %}
    {% set deSlug = craft.entries.id(naviItem.id).locale('de').first().uri %}

    {# Define a variable `activeClass` if the URL segment matches one of the slug translations #}
    {% if segment == enSlug or segment == frSlug or segment == deSlug %}
        {% set activeClass = ' active' %}
    {% endif %}

    <li>
        {# If the `activeClass` var is set, add its value to the link's classes #}
        <a href="{{ naviItem.url }}" class="defaultClasses{{ activeClass ? activeClass }}">
            {{ naviItem.naviTitel }}
        </a>
    </li>

{% endfor %}
{% endcache %}
  • Hmm. That doesn't work. It adds either a active class to every link or to no link. On second tought I'm not sure if its necessary to trigger the locales at all. Wouldn't it be enough to add a listener for the project_entry slug and then add active to the project link? But maybe this is all too much fuss, I guess hardcoding each navi link is just easier. But thanks anyway. The learning curve from such posts is still immense. – KSPR Aug 13 '14 at 18:02
  • C'mon, it's too late to backpedal. I'd try s.th. like this {{ segment ~ ' == ' ~ enSlug ~ ' == ' ~ deSlug }}?? anywhere within your loop to find the problem! – carlcs Aug 13 '14 at 18:14
  • That returns Unexpected token "name" of value "segment" ("end of print statement" expected) on the line of the if statement. – KSPR Aug 13 '14 at 18:24
  • Remove everything after the set lines and use the print statement to get the string values you need to compare. – carlcs Aug 13 '14 at 18:42
  • I'm getting closer. {{ activeClass ? activeClass }} only works inside the if statement. When outside I get Variable "activeClass" does not exist – KSPR Aug 13 '14 at 18:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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