Konfiguration

Alle Konfigurationsvariablen, die für eine vollständig internationalisierte Site benötigt werden.

Internationalization (i18n) in Qgoda has to be explicitely activated in the configuration file _qgoda.yaml. Although there are many options available to customize your multilingual setup, you can get started with setting just two configuration variables linguas and po.textdomain.

Globale Konfiguration

A typical multilanguage configuration in _qgoda.yaml looks like this:

linguas: [en-us, bg, de]
po:
  textdomain: net.qgoda.www
  msgid-bugs-address: Guido Flohr <guido.flohr@cantanea.com>
  copyright-holder: cantanea EOOD <http://www.cantanea.com/>
  reload: 1

linguas

Eine zu RFC4647 section 2.1 konforme Liste von Sprachbezeichnern, jedoch ohne den Stern (*), der in diesem Kontext keinen Sinn ergibt.

Die erste Sprache ist die Default-Sprache der Site.

Die Variable muss gesetzt sein!

po.textdomain

Ein beliebiger Bezeichner für die Website. Die einzige Anforderung besteht darin, dass es sich um einen validen Dateinamen für das jeweilige Betriebssystem handeln muss. Häufig benutzt wird der umgedrehte Host-Name der Site (zum Beispiel net.qgoda.www) oder ein einfaches Wort wie messages. In diesem Kontext hat die Variable wenig Bedeutung.

Dennoch muss auch diese Variable gesetzt sein.

po.msgid-bugs-address

Eine Adresse, der Probleme mit dem zu übersetzenden Originaltext gemeldet werden können. Die Variable ist optional.

po.copyright-holder

Eine Copyright-Angabe für die Texte im Original. Die Variable ist optional.

po.reload

Sollte auf 1 gesetzt werden, wenn Übersetzungen ohne Neustart von Qgoda sichtbar sein sollen, nachdem sie in .mo-Dateien kompiliert und installiert wurden.

Normalerweise werden Übersetzungen nur einmal geladen, wenn Qgoda startet. Danach werden sie aus dem Cache ausgeliefert. Wird po.reload auf 1 gesetzt, resultiert daraus ein minimaler Performanceverlust als Preis für eine einfachere Handhabung, während die Site übersetzt wird.

po.mdextra

Eine Liste von Suchmustern für weitere Markdown-Dateien. Standardmäßig werden alle Dokumente mit Titelei als potenziell übersetzbar angesehen. Falls eine Site weitere übersetzbare Markdown-Dateien aufweist, können sie hier gelistet werden.

Diese Variable ist optional und wird äußerst selten genutzt.

po.views

A list of file name patterns for template files to search for translatable strings. It defaults to just _views or whatever the configuration variable paths.views points to.

po.xgettext-tt2

Der vollständige Pfad zum Program xgettext-tt2, falls es nicht in $PATH enthalten ist. Das Programm xgettext-tt2 wird mit Template-Plugin-Gettext, das als direkte Abhängigkeit mit Qgoda mitinstalliert wird.

po.xgettext

Der vollständige Pfad zum Program xgettext, falls es nicht in $PATH enthalten ist. Das Programm xgettext ist normalerweise in einem Softwarepaket namens gettext oder gettext-tools enthalten.

po.msgfmt

Der vollständige Pfad zum Program msgmerge, falls es nicht in $PATH enthalten ist. Das Programm msgmerge ist normalerweise in einem Softwarepaket namens gettext oder gettext-tools enthalten.

po.msgmerge

Der vollständige Pfad zum Program msgmerge, falls es nicht in $PATH enthalten ist. Das Programm msgmerge ist normalerweise in einem Softwarepaket namens gettext oder gettext-tools enthalten.

po.qgoda

Der vollständige Pfad zum Program qgoda, falls es nicht in $PATH enthalten ist.

Konfiguration der Dokumentensprache

Qgoda muss wissen, in welcher Sprache ein bestimmtes Dokument verfasst ist. In der Praxis bedeutet dies, dass die Variable asset.lingua einen entsprechenden Wert, nämlich einen Sprachbezeichner gemäß RFC4647 Abschnitt 2.1 haben muss, allerdings ohne Wildcards (*).

Es gibt mehrere Möglichkeiten, asset.lingua zu setzen:

Per Dokument

Die Sprache kann in der Titelei des Dokuments gesetzt werden:

---
title: Kalevala
lingua: fi
name: kalevala
---

Per Verzeichnis/Suchmuster

You can save typing by specifying defaults for asset.lingua in the global configuration file _qgoda.yaml:

defaults:
  - files: 
      - /en
      - *.en.md
    values:
      lingua: en

Auf diese Art würde asset.lingua für alle Dateien im Verzeichnis /en auf der obersten Verzeichisebene, sowie für alle Namen, die auf .en.md enden, auf en gesetzt. Siehe Defaults and Suchmusterlisten für weitere Informationen.

Language-Independent Identifier asset.name

All language variants of the same content should share a common property that acts as a link between them. Although you are free to use any variable name you like, asset.name is used throughout this documentation.

For obvious reasons, this identifier will always be configured in the document front matter.

Take for example a markdown file special-relativity.md:

---
title: Special Relativity
lingua: en
name: special-relativity
...

If the German translation of that file is spezielle-relativitaetstheorie.md, that translation's front matter will look like this:

---
title: Spezielle Relativitätstheorie
lingua: de
name: special-relativity
...

Both documents are alternate versions of the same content. They differ in the property asset.lingua but they share a common value for the asset.name property.

Now it is trivial to link from the English version of that document to the German version:

<a href="[% q.link(name=asset.name lingua='fr') %]>German version</a>

And you can link from other documents to the document about Einstein's special relativity regardless of the language like this:

See [% q.anchor(name='special-relativity' lingua=asset.lingua) %]!

And since you almost always want to link to documents in the same language as the current one, there is a shortcut version for the above:

See [% q.lanchor(name='special-relativity') %]!

By using q.lanchor() instead of q.anchor() you can omit the lingua parameter as it is implied. See Referencing Languages for more information about this.

Dateien und Verzeichnisstruktur

There are many different conventions for the directory structure and the file names on internationalized sites:

  • You can use per-language top-level directories like /en, /de, /fr and so on. This is a simple and robust approach.
  • Especially, when you are doing content negotiation with the apache, web server you may consider encoding the language into the filename. You would then not name your documents index.html but for example index.html.en or even index.en.html.
  • You can also make do with encoding the language into the filename or directory of the output document. Qgoda will assist you with this approach by issuing a warning if one document overwrites another.

The Home Page

In a multilingual site, every document can be available in one or more languages. Unfortunately, there is only one /index.html and therefore the sites home page or start page can exist in only one language.

One way to solve this problem is to use your site's default language for /index.html. But there are smarter options:

You can use JavaScript to determine the user's preferred language and redirect them:

---
location: index.html
view: raw
---
<!DOCTYPE html>
<html>
  <head>
    <title>Qgoda Static Site Generator</title>
  </head>
  <body>
<script>
    var lingua,
        default_lingua = '[% config.linguas.0 %]',
        supported = {};
    [% FOREACH lingua IN config.linguas %]
        supported['[% lingua %]'] = true;
    [% END %]

    for (i = 0;  
         navigator.languages != null && i < navigator.languages.length; 
         ++i) {
        var lang = navigator.languages[i].substr(0, 2);
        if (supported[lang]) {
            lingua = lang;
        }
    }

    if (lingua == null) {
        lingua = navigator.language || navigator.userLanguage;
        if (lingua != null) {
            lingua = lingua.substr(0, 2);
        }
    }

    if (!supported[lingua])
        lingua = default_lingua;

    // This is based on the assumption that the start URI for language 'xy'
    // is '/xy'. Change that to your needs!
    document.location.href = '/' + lingua + '/';
    </script>
    <noscript>
<p>Please select your preferred language:</p>
<ul>
[% FOREACH lingua IN config.linguas %]
  <li><a href="/[% lingua %]/">[% lingua %]</a></li>
[% END %]
</ul>
    </noscript>
  </body>
</html>

The above code assumes that you have top-level per-language directories like /en/, /fr/, and so on. If you choose a different directory layout, you have to change the link targets in lines 40 and 46 accordingly.

The best solution is to let the server redirect the user to their preferred language. Read on about content negotiation below.

Content-Negotiation

Content negotiation happens when a web server (nginx, apache, ...) selects the appropriate language version of a piece of content based on the visitor's preference laid forth in their browser language preferences. See Simple Content Negotiation for Nginx for all the gory details of that. Contrary to what the name of the article suggests, it will shed sufficient light on the topic also for users of other web servers than nginx.

Content negotiation can be made arbitrarily complicated. In practice there is one single valid strategy: A visitor of your start page http://YOURDOMAIN should be redirected to the start page in their preferred language and from that moment on they should be pinpointed to that language until they change it. That means that you have to implement content negotiation only for the start page which simplifies things a lot. This is because there is only room for one /index.html and the best strategy is to make that just an entry point that brings you to the content in your preferred language.

Server-side solutions are described at the above mentioned blog post Simple Content Negotiation for Nginx but as a fallback and short of better ideas feel free to steal the start page for this site from https://github.com/gflohr/qgoda-site/blob/main/index.html.

Diese Website verwendet Cookies und ähnliche Technologien, um gewisse Funktionalität zu ermöglichen, die Benutzbarkeit zu erhöhen und Inhalt entsprechend ihren Interessen zu liefern. Über die technisch notwendigen Cookies hinaus können abhängig von ihrem Zweck Analyse- und Marketing-Cookies zum Einsatz kommen. Sie können ihre Zustimmung zu den vorher erwähnten Cookies erklären, indem sie auf "Zustimmen und weiter" klicken. Hier können sie Detaileinstellungen vornehmen oder ihre Zustimmung - auch teilweise - mit Wirkung für die Zukunft zurücknehmen. Für weitere Informationen lesen sie bitte unsere Datenschutzerklärung.