Thanks again @MichaelCurrin!
Duly noted.
I have looked it up and understand it now. It appears I had tried using a map before (copying the structure used for the files containing translation strings), but my liquid code was not correct to pick it up
I set the _data/languages.yml
to this:
en: English
de: Deutsch
nl: Nederlands
and the _includes/nav_languages.html
to this:
{% for lang_code in site.languages %}
{% assign lang_name = site.data.languages[lang_code] %}
<a class="dropdown-item" onchange="location = this.value;"
href="{% if lang_code != 'en' %}/{{ lang_code }}{% endif %}{{ page.url | replace: '.html', '' | remove: 'index' }}">{{ lang_name }}</a>
{% endfor %}
I wasn’t sure why you mentioned {% assign lang_code = "en" %}
(assigning a fixed lang_code would only repeatedly show one language in the menu), but I figure that was to introduce the variable used in the next line.
All worked! But then I got thinking that actually the languages should be displayed in alphabetical order, not in whatever order we added them in _config.yml
.
Thinking & experimenting process
To do that, I think, I would need to:
- load the map, and created a sorted array based on the values - is that possible?
I saw something like {% assign languages = site.data.languages | sort_natural: 'name' %}
but, I don’t get where the ‘name’ comes from (?) And how can I set
- base the forloop not on
site.languages
, but on site.data.languages
(I reckon it’s not possible to base the forloop on site.languages
while make its sorting based on the values of another map (site.data.languages
).)
- in each loop, check if the language code is present in
_config.yml
and if not, simply skip it/do nothing. I saw I can use the contain operator for this.
So I tried the following, but that threw an error
{% assign languages = site.data.languages | sort: 'title' %}
{% for language in languages %}
{% assign lang_code = language[0] %}
{% if site.languages contains lang_code %}
{% assign lang_name = language[1] %}
<a class="dropdown-item" onchange="location = this.value;"
href="{% if lang_code != 'en' %}/{{ lang_code }}{% endif %}{{ page.url | replace: '.html', '' | remove: 'index' }}">{{ lang_name }}</a>
{% endif %}
{% endfor %}
So I changed the data back to an array (instead of map) and adjusted the liquid code.
Now I have the following in _data/languages.yml
- code: en
name: English
- code: de
name: Deutsch
- code: nl
name: Nederlands
And is _includes/nav_languages.html
as follows:
{% assign languages = site.data.languages | sort: 'name' %}
{% for language in languages %}
{% if site.languages contains language.code %}
<a class="dropdown-item" onchange="location = this.value;"
href="{% if language.code != 'en' %}/{{ language.code }}{% endif %}{{ page.url | replace: '.html', '' | remove: 'index' }}">{{ language.name }}</a>
{% endif %}
{% endfor %}
And it seems to work Is this a good/sensible approach?
About the page.url
code: this code was already there, from the person creating the site. That code is used in multiple places across the site. I’ll experiment with the ‘pretty permalink’ per your suggestion. (Maybe it doesn’t work with the translation plugin that we use.) Will report back.