Only link to already translated content

Hello!

Right now I am in the process of translating the whole site I built with Hugo into multiple languages. Now I hit two roadblocks that I hope you can help me with:

I want the menu links only link to content that is already translated.
Say we have this setup:

  • The default site language is english
  • Some pages which are linked to from the homepage are already translated to German, but not all of them

If I get to the German home page, I want the links in menus to only point to the already translated pages, the other ones should fall back to the default language.
If I have the about page translated, its link should be /de/about/ but the untranslated blog should use /blog/.

Right now I am using {{ .URL | absLangURL }} in the menu links, but this adds /de/ to every link, not only the translated ones. Is there a clean way to achieve what I want to have?
If not I would like to propose that absLangURL makes this check and decides by itself wether to include the language in the URL or not.

I tried to use {{ if .IsTranslated }} and enable absLangURL based on that, but this does not work for the default language English (which also apparently is translated).

Another problem I have is the general use of the config for language configuration.
Say I have some pages already translated to a new language, but not enough to justify adding an entry in the language switcher for this language.

The language switcher should ideally only have to iterate over .Translations.
This is where the problem arises: I can only create content for languages that have an entry in the Languages part of the config. For example if I have a section with content written in spanish (the individual pages being 1.es.md, 2.es.md, …) it Hugo gives me this error if I don’t have es specified in the config:
executing "section/guidelines.html" at <where .Data.Pages "T...>: error calling where: can't iterate over <nil>

That means that I have to build additional parameters into each of the languages inside the config to make the decision to show them in the switcher based on that like this:
{{ range where .Translations ".Site.Params.enabled" true }}

What I also noticed is that iterating over .Translations does not return the language of the current site, but only all other ones. I know there is also .Site.Languages but this returns languages, not pages sadly.

If there is no better way to handle this, here is what I would like to propose:

  1. .Translations should iterate over all available Languages in the config (alternatively have something like .AllTranslations )

Edit: This showed me that .AllTranslations is actually in place already and working. Nice! It was just not documented.

  1. specifying a language in the config should not be necessary in order to render pages in a new languages.

Maybe I am overlooking something really obvious here. In that case please point me to the right/better way of doing this. I am really grateful for any help!

Thanks a lot,

Leo

I have the same problem now. Who has the solution?

If you want to preserve the order of the languages on all pages:

  1. Make a list of all translations of a specific page
  2. Loop through all languages your site has
  3. For each langauge:
  4. a. check if the language is in translations; if so, then the easiest way to get relevant link is to once again loop through all translations of the page, and if a translation language is equal to the language you want to link, display it
  5. b. check if it is the language of the page you’re displaying; if so display link to self
  6. c. otherwise, display link to home page

Here is the full code:

            {{- $currentPage := . -}}
            {{ $pagelang := .Language.Lang }}
            {{ $translations := slice }}
            {{ range .Translations }}
                {{ $translations = $translations | append .Lang }}
            {{ end }}
            {{ range .Site.Home.AllTranslations }}
                {{ if in $translations .Lang }}
                    {{- $specificLang := .Lang -}}
                    {{ range $currentPage.Translations }}
                        {{ if (eq .Lang $specificLang) }}
                            <a class="translation-exists" href="{{ .Permalink }}">{{ .Lang }}</a>
                        {{ end }}
                    {{ end }}
                {{ else }}
                    {{ if eq .Lang $pagelang }}
                        <a class="translation-exists" href="{{ $currentPage.Permalink }}">{{ .Lang }}</a>
                    {{ else }}
                        <a class="no-translation" href="{{ .Permalink }}">{{ .Lang }}</a>
                    {{ end }}
                {{ end }}
            {{ end }}