How to build a language switcher that covers entries with custom routes? I have a site with a structure and various channels, that live inside that structure.

I started with the language switcher from https://craftcms.stackexchange.com/a/26347/8325; but that will only work for the structure, because I need to build the URLs for some entries that use custom routes manually.

Now I need to build that more complex language switcher.
Here's how I did it with a macro and some custom entry IDs.

In the basic template

{# Set PIDs for important pages #}
{% set pidNews = 214 %}
{% set pidPressReleases = 208 %}
{% set pidAgenda = 224 %}
{% set pidJobs = 227 %}

{# Section Ids #}

{% set sectionIdPages = 1 %}
{% set sectionIdNews = 2 %}
{% set sectionIdEvents = 3 %}
{% set sectionIdJobs = 6 %}

{# Type Ids #}

{% set typeIdNews = 2 %}
{% set typeIdPressReleases = 14 %}


In the Langswitcher partial

{# Detail views with special routes (news,jobs,events): generate the path by hand #}
{% macro getTranslatedLink(parentPageId, entry, site, currentSite, otherUrl, loop) %}
  {% set otherEntry = craft.entries.id(entry.id).site(site).one() %}
    {% if otherEntry %}
      {% set otherSlug = otherEntry.uri %}
        {% if parentPageId %}
        {% set otherParentPageUrl = craft.entries.section('pages').site(site).id(parentPageId).one().getUrl() %}
        {% set otherUrl = otherParentPageUrl ~ '/' ~ otherSlug %}
        {% else %}
          {% set otherUrl = otherEntry.getUrl() %}
        {% endif %}
    {% endif %}
    {# return the link #}
    &lt;a href="{{ otherUrl }}" class="{% if currentSite.id == site.id %} active{% endif %}"&gt;{{ site.name }}&lt;/a&gt;{{ loop.last ? '' : '|'}}
{% endmacro %}

&lt;ul class="servicenav"&gt;
  {% for site in currentSite.group.sites %}
    &lt;li&gt;
      {# Set fallback value #}
      {% set otherUrl = alias(site.baseUrl) %}
      {% if entry is defined %}
        {% switch entry.sectionId %}
        {# Construct the URLs for news/mm, events, jobs detail pages #}
        {# News #}
        {% case sectionIdNews %}
          {# Press Releases #}
          {% if entry.typeId == typeIdPressReleases %}
          {{ _self.getTranslatedLink(pidPressReleases, entry, site, currentSite, otherUrl, loop) }}
          {# News #}
          {% else %}
            {{ _self.getTranslatedLink(pidNews, entry, site, currentSite, otherUrl, loop) }}
          {% endif %}
        {% case sectionIdEvents %}
          {{ _self.getTranslatedLink(pidNews, entry, site, currentSite, otherUrl, loop) }}
        {% case sectionIdJobs %}
          {{ _self.getTranslatedLink( pidJobs,entry, site, currentSite, otherUrl, loop) }}
        {# Pages #}
        {% default %}
          {{ _self.getTranslatedLink(null, entry, site, currentSite, otherUrl, loop) }}
      {% endswitch %}
      {% endif %} {# end: if entry is defined #}

    &lt;/li&gt;
  {% endfor %}
&lt;/ul&gt;


It's not extremely elegant, but it's flexible and it apparently works. So I thought I'd share it.