Linz/Urfahr
Hauptstraße 58, 4040 Linz
+43 50 353-300
Linz/Urfahr
Hauptstraße 73, 4040 Linz
+43 50 353-300
Neufelden
Marktplatz 1, 4120 Neufelden
+43 50 353-300
Gleisdorf
Franz Bloder Gasse 4, 8200 Gleisdorf
+43 50 353-300

Craft CMS — Language Switcher Macro

Language Switcher oder wie man heute sagt: Site Switcher. Wird immer dann gebraucht, wenn man eine Website hat von der es mehrere Versionen gibt. Das kann z.B. eine Sprachübersetzung einer Website sein, aber auch andere Anwendungsfälle sind denkbar. Der Regelfall ist wohl aber doch der Language Switcher. Was macht diesen so besonders?

Anforderungen an einen flexiblen Language Switcher im Craft CMS

Wir haben jetzt schon mehrere Kunden Projekte mit einem Language Switcher realisiert (Talentor, Kusser). Dabei wollten wir keinen normalen Language Switcher, der "dumm" einfach einen Parameter in der URL tauscht. Wir wollten flexibel bleiben und jeweils steuern können, was der Language Switcher anzeigt. Rausgekommen ist ein Twig Macro — ja, Macros sind klasse für so etwas — was die meisten Anforderungen erfüllt. Das ganze ist dann immer die Grundlage und wird dann im Projekt erweitert bzw. angepasst.

Code Snippet

      
        {# @var craft \craft\web\twig\variables\CraftVariable #}
{# @var entry \craft\elements\Entry #}
{#
  Language Switcher
  ------------------------------------------------------------
  {% import '_partials/macros/_macro-languageSwitcher.html' as macroLanguageSwitcher  %}
  {{ macroLanguageSwitcher.languageSwitcher({
    sites: ['siteA', 'siteB']
  }, entry) }}
#}

{% macro languageSwitcher(opt, entry) %}
  {% set defaults = {
    cn: 'm-languageSwitcher',
    sites: null | default('all')
  } %}

  {# -- Merge Default with Options -- #}
  {% set opt = opt is defined ? defaults|merge(opt) : defaults %}
  {% if opt.sites is defined and entry is defined %}
    {# -- Get all Handles -- #}
    {% set allSiteHandles = [] %}
    {% for site in craft.app.sites.getAllSites() %}
      {% set allSiteHandles = allSiteHandles|merge([site.handle]) %}
    {% endfor %}

    {% set sites = opt.sites %}
    {% if sites == 'all' %}
      {% set sites = allSiteHandles %}
    {% endif %}

    <nav class="{{ opt.cn }}">
      <ul class="{{ opt.cn ~ '__list' }}">
        {% for site in sites %}
          {% if site in allSiteHandles %}

            <li class="{{ opt.cn ~ '__item' }}">
              {% set current = false %}

              {# Check if site equals the requested page site #}
              {% if site == craft.app.sites.currentSite.handle %}
                {% set current = true %}
              {% endif %}

              {% if entry ?? null %}
                {% set siteEntry = craft.entries.id(entry.id).site(site).one() %}

                {% if siteEntry and (siteEntry.site.handle is defined and siteEntry.site.handle == site) %}
                  <a href="{{ siteEntry.getUrl() }}"
                     class="{{ opt.cn ~ '__link' }}{{ current ? ' ' ~ opt.cn ~ '__link--current' }}">
                    {{ site }}
                  </a>
                {% else %}
                  <a href="{{ siteUrl }}"
                     class="{{ opt.cn ~ '__link' }}{{ current ? ' ' ~ opt.cn ~ '__link--current' }}">
                    {{ site }}
                  </a>
                {% endif %}
              {% else %}
                <a href="{{ siteUrl ~ craft.app.request.pathInfo }}"
                   class="{{ opt.cn ~ '__link' }}{{ current ? ' ' ~ opt.cn ~ '__link--current' }}">
                  {{ site }}
                </a>
              {% endif %}
            </li>
          {% endif %}
        {% endfor %}
      </ul>
    </nav>
  {% endif %}
{% endmacro %}
      
    

Zeile 7-11 sind dann interessant, wie man das Ganze einbindet. Wenn man nichts in das Macro reingibt, wird als default "all" gesetzt. Dann werden alle Languages, die es auf der Website gibt, einfach angezeigt. Man hat aber die Möglichkeit, z.B. ein Array mit in das Macro zu übergeben. Dafür nutzt man die Site Handles und kann so ziemlich genau steuern, welche Languages der Switcher anzeigt. Schön flexibel.

Darf auf gern diskutiert werden das Ganze. Schreibt uns einfach auf Twitter ;)