Does anyone have any examples of how they've put together the main site navigation for a multi-lingual site set-up made up of singles, channels and structure?

At the moment I've just hard-coded the nav and done and if else on the locale ID but would like to know if there's a more flexible, future-proof method.

up vote 3 down vote accepted

This was on my first craft site (http://patisseriejanandries.com) so this is a 'warts and all' example.

Productpages was a structure, news a channel, the other pages were singles. The 'nieuwsindex' single is there because I needed a translatable url for the news page, so that single served as a workaround. (more on that here: https://plus.google.com/116942350387086245334/posts/TBtR3XwuZGx) You're still basically hardcoding the nav, but craft does take care of the multi-language urls, pretty nice if you ask me.

The nav template looked like this (which IMO isn't that bad for a first try :) )

   {# set values for the navigation #}
   {# products = structure #}
   {% set productpages = craft.entries.section('productPages').depth(1).find() %}
   {# singles #}
   {% set contact = craft.entries.section('contact').find() %}
   {% set overjanandries = craft.entries.section('overJanAndries').find() %}
   {% set overview = craft.entries.section('overview').find() %}
   {% set news = craft.entries.section('nieuwsIndex').find() %}


    <div id="menu">
      <a class="close"> <span class="menu-icon icon-cancel"></span></a>
      <nav role="navigation">
      <ul>
        {% for page in overview %}
          <li>{{ page.getLink() }}</li>  
        {% endfor %}
        {% for page in overjanandries %}
          <li>{{ page.getLink() }}</li>  
        {% endfor %}
        {% for page in productpages %}
         <li>{{ page.getLink() }}</li>  
        {% endfor %}
         {% for page in news %}
          <li>{{ page.getLink() }}</li>  
        {% endfor %}
        {% for page in contact %}
          <li>{{ page.getLink() }}</li>  
        {% endfor %}
      </ul>
      </nav>
    </div><!-- menu -->

Following Christian's suggestions I've amended my code and added a 'current' class. This is working fine (and probably cuts down on DB calls):

{# set values for the navigation #}
{# products = structure #}
{% set productpages = craft.entries.section('productPages').depth(1).find() %}
{# singles #}
{% set contact = craft.entries.section('contact').first() %}
{% set overjanandries = craft.entries.section('overJanAndries').first() %}
{% set overview = craft.entries.section('overview').first() %}
{% set news = craft.entries.section('nieuwsIndex').first() %}
{% set section = craft.request.getSegment(1) %}


<div id="menu">
  <a class="close"> <span class="menu-icon icon-cancel"></span></a>
  <nav role="navigation">
  <ul>
    <li {% if section == overview.uri %}class="current"{% endif %}>{{ overview.getLink() }}</li>  
    <li {% if section == overjanandries.uri %}class="current"{% endif %}>{{ overjanandries.getLink() }}</li>  
    {% for page in productpages %}
     <li {% if section == page.uri %}class="current"{% endif %}>{{ page.getLink() }}</li>  
    {% endfor %}
    <li {% if section == news.uri %}class="current"{% endif %}>{{ news.getLink() }}</li>  
    <li {% if section == contact.uri %}class="current"{% endif %}>{{ contact.getLink() }}</li>  
  </ul>
  </nav>
</div><!-- menu -->
  • 1
    Not bad at all, Erwin! First thing I'd do to further improve on it is to get rid of those for loops to output links to your singles (use first() on the entry query). – carlcs Jul 10 '14 at 11:41
  • I'm giving this one a go because the way my entries are set up in the back end is close to this, but when I view my nav, I get English title output for both languages (although it does output the correct URL slug for the Czech site). – Tyssen Jul 10 '14 at 12:05
  • Also, how would you add an 'active/current/here' class to the link? – Tyssen Jul 10 '14 at 12:09
  • @Tyssen exchange getLink() with getUrl() and title() to better control the html output for your links. Then you can also add CSS classes class="myDefaultClass{{ craft.request.firstSegment == 'mySectionHandle' ? ' current' }} – carlcs Jul 10 '14 at 13:02
  • Oh and I'd definitely think twice about not doing the switch to a "pages" structure. Single content is probably easy to copy over and you can also reuse your fields! – carlcs Jul 10 '14 at 13:07

I have one main structure "pages" and got rid of all single sections. I also gave each channel's index page an entry in the structure (good for URL translation). Then I added some entry types to it (you can also link templates to them) and created my site navigation like in my example code below.

This allows you to translate the slug of the index pages in the CP and you have access to localized URL (page.getUrl) and page title variables (page.title) in your nav template.

Only one level of hierarchy I need. If you have to go deeper, the nav tag's waiting for you! ;)

{# Get top-level entries in pages structure #}
{% set pages = craft.entries.section('pages').level(1) %}

<nav class="navigation" role="navigation">
    <ul>

        {# Loop through entries (= pages) and list the links #}
        {% for page in pages %}
            <li class="navigation-item">
                <a href="{{ page.getUrl }}">{{ page.title }}</a>
            </li>
        {% endfor %}

        {# Include links to switch locales #}
        <li class="navigation-item">
            {% include '_includes/language_switch.html' %}
        </li>

    </ul>
</nav>
  • pretty solid approach, nice one. – erwinheiser Jul 10 '14 at 11:12

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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