🌐 feat(i18n): overhaul translation system & add languages (#145)

Revamp the existing translation system, simplifying
management and adding several new languages. The new system reads from
TOML files in the `/i18n` directory and improves template structures.
It also enhances customisation options and robustness by providing
fallbacks and modularity.

- Implement a new, streamlined translation macro.
- Load translations from `/i18n` TOML files.
- Remove redundant configuration requirements.
- Refactor templates to align with new i18n system.
- Add support for Hindi, Japanese, Russian, Portuguese, Chinese,
  Italian, German, Ukranian, Korean, and French languages.
- Credit Thomas Weitzel (@thomasweitzel) for inspiration.
This commit is contained in:
Óscar
2023-09-12 18:58:58 +02:00
committed by GitHub
parent 327545f2d5
commit 32a2d5094b
46 changed files with 1534 additions and 483 deletions

View File

@@ -65,23 +65,23 @@
{% set current_year = now() | date(format="%Y") %}
{# Translate the copyright if set in the config #}
{%- if config.extra.translate_copyright -%}
<p>{{ macros_translate::translate(key="copyright", default=config.extra.copyright) | replace(from="$CURRENT_YEAR", to=current_year) | replace(from="$SEPARATOR", to=separator) | markdown | safe }}</p>
<p>{{ macros_translate::translate(key="copyright", default=config.extra.copyright, language_strings=language_strings) | replace(from="$CURRENT_YEAR", to=current_year) | replace(from="$SEPARATOR", to=separator) | markdown | safe }}</p>
{%- else -%}
<p>{{ config.extra.copyright | replace(from="$CURRENT_YEAR", to=current_year) | replace(from="$SEPARATOR", to=separator) | markdown | safe }}</p>
{%- endif -%}
{%- endif -%}
{# Shows "Powered by Zola & tabi" notice #}
{{ macros_translate::translate(key="powered_by", default="Powered by") }}
{{ macros_translate::translate(key="powered_by", default="Powered by", language_strings=language_strings) }}
<a rel="{{ rel_attributes }}" {{ blank_target }} href="https://www.getzola.org">Zola</a>
{{ macros_translate::translate(key="and", default="&") }}
{{ macros_translate::translate(key="and", default="&", language_strings=language_strings) }}
<a rel="{{ rel_attributes }}" {{ blank_target }} href="https://github.com/welpo/tabi">tabi</a>
{# Shows link to remote repository #}
{%- if config.extra.remote_repository_url and config.extra.show_remote_source | default(value=true) -%}
{{ separator }}
<a rel="{{ rel_attributes }}" {{ blank_target }} href="{{ config.extra.remote_repository_url }}">
{{ macros_translate::translate(key="site_source", default="Site source") }}
{{ macros_translate::translate(key="site_source", default="Site source", language_strings=language_strings) }}
</a>
{%- endif -%}
</small>

View File

@@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{# Site title #}
<title>{{ macros_set_title::set_title() }}</title>
<title>{{ macros_set_title::set_title(language_strings=language_strings) }}</title>
{# Favicon #}
{% if config.extra.favicon %}

View File

@@ -0,0 +1,43 @@
<li class="language-switcher">
<div class="dropdown" type="Button">
<div class="language-switcher-icon"></div>
<div class="dropdown-content">
{#- Display the current language first in the dropdown -#}
{{ macros_translate::translate(key="language_name", default=lang, language_strings=language_strings) }}
{#- Loop through all the available languages in the config -#}
{%- for lcode, ldetails in config.languages -%}
{#- Skip the current language to avoid linking to the current page -#}
{%- if lang == lcode -%}
{%- continue -%}
{%- endif -%}
{#- Dynamically load the language strings for each language -#}
{%- set other_language_strings = load_data(path="i18n/" ~ lcode ~ ".toml", required=false) -%}
{%- if not other_language_strings -%}
{%- set other_language_strings = load_data(path="themes/tabi/i18n/" ~ lcode ~ ".toml", required=false) -%}
{%- endif -%}
{#- Use the loaded language strings to get the language name -#}
{% set language_name = macros_translate::translate(key="language_name", default=lcode,
language_strings=other_language_strings) %}
{#- Check if the language code matches the default language -#}
{%- if lcode == config.default_language -%}
{#- If it does, link to the root path (no language code in URL) -#}
<a type="Button" href="{{ current_url | replace(from='/' ~ lang ~ '/', to = '/') }}">{{ language_name }}</a>
{%- elif lang == config.default_language -%}
{#- Check if the current language is the default language -#}
{#- If it is, append the language code to the base URL -#}
<a type="Button" href="{{ config.base_url }}/{{ lcode }}{{ current_path | default(value=" /") | safe }}">{{
language_name }}</a>
{%- else -%}
{#- If it's not, replace the current language code in the URL with the new one -#}
<a type="Button" href="{{ current_url | replace(from='/' ~ lang ~ '/', to='/' ~ lcode ~ '/') }}">{{
language_name }}</a>
{%- endif -%}
{%- endfor -%}
</div>
</div>
</li>

View File

@@ -12,7 +12,7 @@
<li>
{% set trailing_slash = menu.trailing_slash | default(value=true) %}
<a class="nav-links no-hover-padding" href="{{ get_url(path=menu.url, lang=lang, trailing_slash=trailing_slash) }}"/>
{{ macros_translate::translate(key=menu.name, default=menu.name) }}
{{ macros_translate::translate(key=menu.name, default=menu.name, language_strings=language_strings) }}
</a>
</li>
{% endfor %}
@@ -21,37 +21,7 @@
{# Language switcher #}
{# Display the language switcher only if more than one language is available #}
{%- if config.languages | length > 0 %}
<li class="language-switcher">
<div class="dropdown" type="Button">
<div class="language-switcher-icon"></div>
{# Display the current language first in the dropdown #}
<div class="dropdown-content">
{{ macros_translate::translate(key="language_name", default=config.extra.language_name.en) }}
{# Loop through all the available languages in the config #}
{%- for lcode, language_name in config.extra.language_name -%}
{# Skip the current language to avoid linking to the current page #}
{%- if lang != lcode -%}
{# Check if the language code matches the default language #}
{%- if lcode == config.default_language -%}
{# If it does, link to the root path (no language code in URL) #}
<a type="Button" href="{{ current_url | replace(from='/' ~ lang ~ '/', to = '/') }}">{{ language_name }}</a>
{%- else -%}
{# Check if the current language is the default language #}
{%- if lang == config.default_language -%}
{# If it is, append the language code to the base URL #}
<a type="Button" href="{{ config.base_url }}/{{ lcode }}{{ current_path | default(value="/") | safe }}">{{ language_name }}</a>
{%- else -%}
{# If it's not, replace the current language code in the URL with the new one #}
<a type="Button" href="{{ current_url | replace(from='/' ~ lang ~ '/', to='/' ~ lcode ~ '/') }}"/>{{ language_name }}</a>
{%- endif -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</div>
</div>
</li>
{% include "partials/language_switcher.html" %}
{%- endif %}
{# Theme switcher #}