<p>I've used the code provided by carlcs and it works great (many thanks for the sample code).
I did have to make an adjustment for cases where an entry wasn't translated in every locale.
Would have put this in a comment but don't have enough reputation.</p>

<p>Nothing fancy, just added another if. Here's what i ended up with:</p>

<pre><code>{% set locales = ['nl_be', 'fr_be', 'en'] %}
{% for locale in locales %}

    {# Check if locale equals the requested page locale #}
    {% if locale == craft.locale %}
        {% set current = true %}
    {% else %}
        {% set current = false %}
    {% endif %}


    {# Is this an entry page? #}
    {% if entry is defined %}



        {# Find the current entry in the other locale#}
        {% set localeEntry = craft.entries.id(entry.id).locale(locale).first %}

        {# Make sure that the localised entry exists#}
        {% if localeEntry %}

            {# Make sure that it's actually localized to this locale#}
            {% if localeEntry.locale == locale %}

                {# Output a link to it #}
                &lt;a href="{{ localeEntry.getUrl() }}" class="nav-link{{ current ? ' current'}}"&gt;{{ craft.i18n.getLocaleById(locale).id[:2] }}&lt;/a&gt;

            {% else %}

                {# Output a link to the hompage #}
                &lt;a href="{{ craft.config.siteUrl[locale] }}" class="nav-link{{ current ? ' current'}}"&gt;{{ craft.i18n.getLocaleById(locale).id[:2] }}&lt;/a&gt;

            {% endif %}
        {% else %}

            {# Output a link to the hompage #}
            &lt;a href="{{ craft.config.siteUrl[locale] }}" class="nav-link{{ current ? ' current'}}"&gt;{{ craft.i18n.getLocaleById(locale).id[:2] }}&lt;/a&gt;
        {% endif %}
    {# Not an entry page #}
    {% else %}

        {# Output the same path with the locale's base URL (`siteUrl`) #}
        &lt;a href="{{ craft.config.siteUrl[locale] ~ craft.request.getPath() }}" class="nav-link{{ current ? ' current'}}"&gt;{{ craft.i18n.getLocaleById(locale).id[:2] }}&lt;/a&gt;

    {% endif %}
{% endfor %}
</code></pre>

CC BY-SA 3.0
2014-08-06T16:36:19.223Z
Steven, what's the reason for that new conditional?`localeEntry.locale == locale` is not working for you? This is actually the conditional that should check if the entry is translated to that locale.
carlcs
CC BY-SA 3.0
2014-08-07T12:31:06.950Z
`localeEntry.locale == locale` wasn't working for me. I had entries that didn't exist in all languages and that part threw a template error:  `Impossible to access an attribute ("locale") on a NULL variable ("")`
Steven Vandemoortele
CC BY-SA 3.0
2014-08-07T15:08:15.670Z
Ahh OK., I didn't know that this is possible. Is this because you added locales after that entry already existed?
carlcs
CC BY-SA 3.0
2014-08-07T15:29:18.120Z
No, you can use the switch buttons on the right of an entry in the cms to disable/enable an entry per locale. http://imgur.com/rPiObyN
Steven Vandemoortele
CC BY-SA 3.0
2014-08-06T15:34:13.467Z
2014-08-06T15:34:13.467Z
Steven Vandemoortele
<p>This is because you loop through all but the current locales. Remove the <code>without</code> filter to loop them all.</p>

<blockquote>
  <p><code>{% set otherLocales = craft.i18n.getSiteLocaleIds()|without(craft.locale) %}</code></p>
</blockquote>

<p>.</p>

<p>Add "current" class:</p>

<p>To assign the current locale's link a class of "current", compare the looped locale to the current locale and set a variable that you can later test for. (In the example code I use the <a href="http://twig.sensiolabs.org/doc/templates.html#other-operators" rel="nofollow noreferrer">ternary operator</a> for short output syntax.)</p>

<p>.</p>

<p>Example Code:</p>

<p>With my example code below you first create an array of all the locales you want the language switch to include, and then loop through it. With this technique you can define the order of the output manually or exclude locales from the loop.</p>

<pre><code>{# Configure and loop through selected site locales #}
{% set locales = ['en', 'hu'] %}
{% for locale in locales %}

    {# Check if locale equals the requested page locale #}
    {% set current = false %}
    {% if locale == craft.locale %}
        {% set current = true %}
    {% endif %}

    {# Is this an entry page? #}
    {% if entry is defined %}

        {# Find the current entry in the other locale #}
        {% set localeEntry = craft.entries.id(entry.id).locale(locale).first() %}

        {# Make sure that it's actually localized to this locale #}
        {% if localeEntry and localeEntry.locale == locale %}

            {# Output a link to it #}
            &lt;a href="{{ localeEntry.getUrl() }}" class="nav-link{{ current ? ' current'}}"&gt;{{ craft.i18n.getLocaleById(locale).name }}&lt;/a&gt;

        {% else %}

            {# Output a link to the hompage #}
            &lt;a href="{{ craft.config.siteUrl[locale] }}" class="nav-link{{ current ? ' current'}}"&gt;{{ craft.i18n.getLocaleById(locale).name }}&lt;/a&gt;

        {% endif %}

    {# Not an entry page #}
    {% else %}

        {# Output the same path with the locale's base URL (`siteUrl`) #}
        &lt;a href="{{ craft.config.siteUrl[locale] ~ craft.request.getPath() }}" class="nav-link{{ current ? ' current'}}"&gt;{{ craft.i18n.getLocaleById(locale).name }}&lt;/a&gt;

    {% endif %}

{% endfor %}
</code></pre>

<p><em>Code edits done to implement a lookup of the (translated) locale name as described <a href="https://craftcms.stackexchange.com/a/880/125">here</a> by Brandon Kelly</em></p>

<p>.</p>

<p>Notes:</p>

<ul>
<li>The easiest (and recommended) way to use this language switch is to exclusively use    entry pages (channel entries, structure entries, or singles) on your site.</li>
<li>All non entry pages have to have the same URL path / slug for each locale (eg. <code>http://craft.dev/de/meineindexseite/</code> and <code>http://craft.dev/en/meineindexseite/</code>), translated URL parts won't work for non entry pages with this code.</li>
<li>If you only use entry pages or if you are using <a href="http://buildwithcraft.com/docs/templating-overview#template-localization" rel="nofollow noreferrer">localized template folders</a> you should be save to remove the <code>entry is defined</code> conditional (incl. the else part) altogether.</li>
<li><code>craft.config.siteUrl[localeId]</code> only works if <a href="http://buildwithcraft.com/docs/config-settings#siteUrl" rel="nofollow noreferrer">siteUrl is configured</a> to take care of localized URLs</li>
</ul>

CC BY-SA 3.0
2014-07-10T03:02:56.773Z
Good to hear, @simon! Just added some additional info for you.
carlcs
CC BY-SA 3.0
2016-10-31T18:50:04.950Z
Is it possibly to jump on this question? I'm using the above code which is working fine expect on my 404 page. I have two locales (en_gb and en_de) and I get this error: _Key "en_gb" for array with keys "en, de" does not exist in "_layout" at line 91_
richardpixel
CC BY-SA 3.0
2014-07-10T01:10:50.563Z
2017-10-05T12:30:57.063Z
2017-10-05T12:30:57.063Z
carlcs
<p>I’m trying to create a dropdown menu to switch between language’s on my site. I am currently doing this with this snippet found on the google plus community:</p>

<pre><code>{% block locale__switch %}

{# Loop through all of the site locales, except the current one #}
{% set otherLocales = craft.i18n.getSiteLocaleIds()|without(craft.locale) %}
{% for locale in otherLocales %}

    {# Find the current entry in the other locale #}
    {% set localeEntry = craft.entries.id(entry.id).locale(locale).first %}

    {# Make sure that it's actually localized to this locale #}
    {% if localeEntry.locale == locale %}

        {# Output a link to it #}
        &lt;a href="{{ localeEntry.getUrl() }}" style="text-transform:uppercase;"&gt;{{ locale }}&lt;/a&gt;
    {% else %}

        {# Output a link to the hompage #}
        &lt;a href="{{ craft.config.siteUrl[locale] }}" style="text-transform:uppercase;"&gt;{{ locale }}&lt;/a&gt;
    {% endif %}

    {% endfor %}
{% endblock %} 
</code></pre>

<p>But this simply shows a single link to the opposite locale than the current. Basically I want to have something like this: </p>

<pre><code> &lt;div id="lang-form"&gt;
    &lt;div id="language-selected" class="dropdownbox"&gt;EN &amp;#9662;&lt;/div&gt;

    &lt;div id="dropdown-wrapper"&gt;
      &lt;ul name="lang" id="select-language-menu" class="menu"&gt;
          &lt;li class="selected"&gt;
               English
               &lt;div class="lang-code" style="display: none;"&gt;en &amp;#9662;&lt;/div&gt;
          &lt;/li&gt;
          &lt;li&gt;
               Hungarian
               &lt;div class="lang-code" style="display: none;"&gt;hu &amp;#9662;&lt;/div&gt;
          &lt;/li&gt;
       &lt;/ul&gt;
     &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
</code></pre>

<p>This probably seems trivial and simple, but I’m having a tough time figuring out how craft works at this level. Any ideas?</p>

<localization><navigation><drop-down>
How do I create a locale dropdown to switch between languages?
# How do I create a locale dropdown to switch between languages?

(Asked by: username_0 on 2014-07-10)

I’m trying to create a dropdown menu to switch between language’s on my site. I am currently doing this with this snippet found on the google plus community:
{% block locale__switch %}

{# Loop through all of the site locales, except the current one #}
{% set otherLocales = craft.i18n.getSiteLocaleIds()|without(craft.locale) %}
{% for locale in otherLocales %}

    {# Find the current entry in the other locale #}
    {% set localeEntry = craft.entries.id(entry.id).locale(locale).first %}

    {# Make sure that it's actually localized to this locale #}
    {% if localeEntry.locale == locale %}

        {# Output a link to it #}
        {{ locale }}
    {% else %}

        {# Output a link to the hompage #}
        {{ locale }}
    {% endif %}

    {% endfor %}
{% endblock %} 

But this simply shows a single link to the opposite locale than the current. Basically I want to have something like this: 
 
    EN ▾

    
      
          
               English
               en ▾
          
          
               Hungarian
               hu ▾
          
       
     
    
  

This probably seems trivial and simple, but I’m having a tough time figuring out how craft works at this level. Any ideas?

**Tags:** localization, navigation, drop-down


---

## 2 answers

### Answer by username_2 on 2014-07-10. Score: 15 | Accepted answer

This is because you loop through all but the current locales. Remove the without filter to loop them all.

{% set otherLocales = craft.i18n.getSiteLocaleIds()|without(craft.locale) %}

.
Add "current" class:
To assign the current locale's link a class of "current", compare the looped locale to the current locale and set a variable that you can later test for. (In the example code I use the ternary operator for short output syntax.)
.
Example Code:
With my example code below you first create an array of all the locales you want the language switch to include, and then loop through it. With this technique you can define the order of the output manually or exclude locales from the loop.
{# Configure and loop through selected site locales #}
{% set locales = ['en', 'hu'] %}
{% for locale in locales %}

    {# Check if locale equals the requested page locale #}
    {% set current = false %}
    {% if locale == craft.locale %}
        {% set current = true %}
    {% endif %}

    {# Is this an entry page? #}
    {% if entry is defined %}

        {# Find the current entry in the other locale #}
        {% set localeEntry = craft.entries.id(entry.id).locale(locale).first() %}

        {# Make sure that it's actually localized to this locale #}
        {% if localeEntry and localeEntry.locale == locale %}

            {# Output a link to it #}
            {{ craft.i18n.getLocaleById(locale).name }}

        {% else %}

            {# Output a link to the hompage #}
            {{ craft.i18n.getLocaleById(locale).name }}

        {% endif %}

    {# Not an entry page #}
    {% else %}

        {# Output the same path with the locale's base URL (`siteUrl`) #}
        {{ craft.i18n.getLocaleById(locale).name }}

    {% endif %}

{% endfor %}

Code edits done to implement a lookup of the (translated) locale name as described here by Brandon Kelly
.
Notes:

The easiest (and recommended) way to use this language switch is to exclusively use    entry pages (channel entries, structure entries, or singles) on your site.
All non entry pages have to have the same URL path / slug for each locale (eg. http://craft.dev/de/meineindexseite/ and http://craft.dev/en/meineindexseite/), translated URL parts won't work for non entry pages with this code.
If you only use entry pages or if you are using localized template folders you should be save to remove the entry is defined conditional (incl. the else part) altogether.
craft.config.siteUrl[localeId] only works if siteUrl is configured to take care of localized URLs

> **Comments:**
> **username_2**: Good to hear, @simon! Just added some additional info for you.  
> **username_3**: Is it possibly to jump on this question? I'm using the above code which is working fine expect on my 404 page. I have two locales (en_gb and en_de) and I get this error: _Key "en_gb" for array with keys "en, de" does not exist in "_layout" at line 91_  

---

### Answer by username_1 on 2014-08-06. Score: 5

I've used the code provided by username_2 and it works great (many thanks for the sample code).
I did have to make an adjustment for cases where an entry wasn't translated in every locale.
Would have put this in a comment but don't have enough reputation.
Nothing fancy, just added another if. Here's what i ended up with:
{% set locales = ['nl_be', 'fr_be', 'en'] %}
{% for locale in locales %}

    {# Check if locale equals the requested page locale #}
    {% if locale == craft.locale %}
        {% set current = true %}
    {% else %}
        {% set current = false %}
    {% endif %}


    {# Is this an entry page? #}
    {% if entry is defined %}



        {# Find the current entry in the other locale#}
        {% set localeEntry = craft.entries.id(entry.id).locale(locale).first %}

        {# Make sure that the localised entry exists#}
        {% if localeEntry %}

            {# Make sure that it's actually localized to this locale#}
            {% if localeEntry.locale == locale %}

                {# Output a link to it #}
                {{ craft.i18n.getLocaleById(locale).id[:2] }}

            {% else %}

                {# Output a link to the hompage #}
                {{ craft.i18n.getLocaleById(locale).id[:2] }}

            {% endif %}
        {% else %}

            {# Output a link to the hompage #}
            {{ craft.i18n.getLocaleById(locale).id[:2] }}
        {% endif %}
    {# Not an entry page #}
    {% else %}

        {# Output the same path with the locale's base URL (`siteUrl`) #}
        {{ craft.i18n.getLocaleById(locale).id[:2] }}

    {% endif %}
{% endfor %}

> **Comments:**
> **username_2**: Steven, what's the reason for that new conditional?`localeEntry.locale == locale` is not working for you? This is actually the conditional that should check if the entry is translated to that locale.  
> **username_1**: `localeEntry.locale == locale` wasn't working for me. I had entries that didn't exist in all languages and that part threw a template error:  `Impossible to access an attribute ("locale") on a NULL variable ("")`  
> **username_2**: Ahh OK., I didn't know that this is possible. Is this because you added locales after that entry already existed?  
> **username_1**: No, you can use the switch buttons on the right of an entry in the cms to disable/enable an entry per locale. http://imgur.com/rPiObyN  

---

