Language switcher in menu

#1

I’m trying to set up a language switcher that fulfils these requirements:

  • the order of the languages should be permanent
  • if there isn’t a translation for that piece of content in the alternate language the button should be disabled or show the result of the Lang.Merge

So far, I came up with this:

{{ if .IsHome }}
	<li><a href="/pt" class="{{- if eq (string .Lang) "pt" -}}active{{- end -}}">Portuguese</a></li>
	<li><a href="/en" class="{{- if eq (string .Lang) "en" -}}active{{- end -}}">English</a></li>
{{ else }}
<li><a href="/pt{{ .Permalink | relURL }}" class="{{- if eq (string .Lang) "pt" -}}active{{- end -}}">Portuguese</a></li>
<li><a href="/en{{ .Permalink | relURL }}" class="{{- if eq (string .Lang) "en" -}}active{{- end -}}">English</a></li>
{{ end }}

But of course, this breaks when there isn’t a translation and is too hard coded. I also tried to range through the translations, but that had two problems:

  • the order of languages would change
  • if there wasn’t an available translation, it would only show one button.

I’m a bit lost as to how to cycle through all the available languages and set the href appropriately.

Is there something I’m missing?

0 Likes

#2

Not sure if it answers your question but, this is what I am doing in my work-in-progress site.

This assumes two languages. It ranges through the translations of the page it’s on, and shows the other one. If there is no translation, it gives a link to the root depending on which language the site is in. In this case, the site is two domains, but in the case a language is in a subfolder, just hard-code the href accordingly.

Side note: I’m using the “bulma” css lib this time around, and while I mostly like it, the way it uses color, is to assign a color to a class with some meaning, like is-primary, is-info, is-danger etc. The color I selected happens to be called is-danger but, it’s semantically meaningless, so it can be ignored. (I need to make some color classes that simply are what they are).

0 Likes

#3

Thanks @RickCogley it helped ! Here’s how the final code turned out:

{{ if .Site.IsMultiLingual }}
	{{ range .Site.Languages }}
	{{ if eq . $.Site.Language }}
		<li><a href="#" class="active language">{{ .LanguageName }}</a></li>
	{{ else }}
		{{ range $.Translations }}
		<li><a href="{{ .Permalink }}" class="">{{ .Language.LanguageName }}</a></li>
		{{ end }}
	{{ end }}
	{{ end }}
{{ end }}

I’m not sure how it would work for sites with 3 or more languages, but in this use case it seems to do the trick.

1 Like

#4

Here is one example (home page only):

This does not take any “lang merge” into account, though. But it should be stable.

1 Like

#5

I do it this way:

4 Likes

[SOLVED] Language switcher: link to current translated content instead of home
Redirect to Translated Version of Current Page with Multilingual Selector
Is there a way to retrieve the value of defaultContentLanguage?
(solved) Problem listing languages in a correct order and switching to a language-specific page URL
#6

Just wanted to say thank you for these answers. I wanted a flag based switcher, so I ended up with something like this code below. I’m not sure if using emoji like that is recommended, or if I should use an SVG or other image(?):

  {{ if .IsTranslated }}
    {{ range .Translations }}
      {{ if eq .Site.Language.Lang "en" }}
    <li><a title="English" href="{{ .RelPermalink }}">&#x1F1EC;&#x1F1E7;</a></li>
      {{ else }}
    <li><a title="Norsk" href="{{ .RelPermalink }}">&#x1F1F3;&#x1F1F4;</a></li>
      {{ end }}
    {{ end }}
  {{ else }}
    {{ if eq .Site.Language.Lang "no" }}
    <li><a title="English" href="/en">&#x1F1EC;&#x1F1E7;</a></li>
    {{ else }}
    <li><a title="Norsk" href="/">&#x1F1F3;&#x1F1F4;</a></li>
    {{ end }}
  {{ end }}
</ul>

(Also not sure if re-opening old threads like this is considered good or bad … :thinking: :innocent:)

0 Likes

#7

generally, new support questions should get their own thread. But yours is more adding to the possibilities. There has been some discussion about using flags for this elsewhere in the forum; it could be considered problematic since flags are nation-based whereas languages are not.

0 Likes

#8

@flips i saw your code, but you had to hard code language cases.

In the spirit (or did I stole it here, can’t remember :-)) of @martignoni example this is what I have for my multilingual site. The partial is universal. I just have to add some entries to config.toml


{{ $siteLanguages := site.Languages}}
{{ $pageLang := .Page.Lang}}
{{- range .Page.AllTranslations }}
    {{ $translation := . }}
    {{- range sort $siteLanguages "Weight" "asc" }}
        {{- if eq $translation.Lang .Lang }}
            {{ if eq $pageLang .Lang}}
                <a class="flagselect" href="{{ $translation.Permalink | relURL }}">{{ .Params.languageNameShort }}{{ .Params.languageFlag }}</a>
            {{ else }}
                <a class="flagnoselect" href="{{ $translation.Permalink | relURL }}">{{ .Params.languageNameShort }}{{ .Params.languageFlag }}</a>
            {{ end }}
        {{- end }}
    {{- end }}
{{- end }}

and on config.toml I have a language subsection for each language

[languages]
    [languages.fr]
        languageName = "Français"
        languageNameShort = "fr"
        languageFlag = "🇫🇷"
        weight = 1
    [languages.en]
        languageName = "English"
        languageNameShort = "en"
        languageFlag = "🇬🇧"
        weight = 3
/* Flags navigation */
.flagselect {
  border: 1px solid #333333;
  padding: 0px;
  margin: 0px;
  font-weight: bold;
  color: black;
  font-size: 90%;
}
.flagnoselect {
  padding: 0px;
  margin: 0px;
  color: #333333;
  font-size: 90%;
}

1 Like