Skip to content

Localization and translations

Carlo Beltrame edited this page Mar 6, 2024 · 7 revisions

eCamp v3 is kindly supported with an Open Source plan at crowdin.com 🎉 🇩🇪 🇫🇷 🇮🇹 🇬🇧

All translations in ecamp3 are situated in JSON files in the git repository. The frontend and print services have separate JSON files, and there is a common directoy containing shared translations. The backend has some translation files in a slightly different format (some of it JSON, some of it YAML) as well.

The JSON files each contain a structure of nested JSON objects (denoted by {} curly braces). To use a translation in the code, we don't write the translated text into the code. Instead, we use a so-called translation key. The key might look something like global.button.edit. This key refers to the following entry in the JSON files:

// example de.json translation file
{
  "global": {
    "button": {
      "delete": "Löschen",
      "edit": "Bearbeiten", // <-- this is the selected translation
      "ok": "OK",
      // more translations...
    },
    // more translations...
  },
  // more translations...
}

Since editing these JSON files by hand is very error-prone, we use crowdin to help us and any translators manage the translations. Crowdin reads the JSON files from the git repository, presents an easy-to-use editor in the form of a web application, and can then export any new or changed translations as a pull request to GitHub.

➡️ If you would like to help improve the translations, you can visit https://translate.ecamp3.ch and sign up as a translator.

For now, we have set up translations for English, German, French, Italian and Rumantsch, each in separate json files. Additionally, we have more specific "scout" versions of these languages, which can override specific translations. An example would be en-CH-scout.json translating entity.user.fields.nickname as "scout name" instead of "nickname".

Rules for working with translations

New translation keys should generally go into the specific JSON files in the frontend or print services. Only when a translation is used in multiple services (in an equivalent place) should it be moved to commons.

When e.g. the same German text is needed in multiple distinct views or components, we generally use separate translation keys. The reason for this is that in other languages (maybe even languages that will be added in the future), the best translation might be different in the two places (maybe a different word is more suitable in one place, or a different capitalization or grammatical case such as accusative is needed, and so on).

The segments of all translation keys should be in camelCase (and start with a lowercase letter).

When adding a new translation, we add it in the git repository in one language only. The translations will then be done later on crowdin. Also, we only add translations to the scout variants if it is really needed.

Translation file structure

In the JSON files, only the following top-level entries are allowed:

  • entity - translations of fieldnames of the entities, such as "motto": "Motto" or "nickname": "Pfadiname"
  • components and views - translations for specific Vue components. The key structure should match exactly the location of the .vue file using the translation, so for instance all translations used in frontend/src/components/camp/ActivityList.vue should have a translation key starting with components.camp.activityList.
  • global - this contains global translations that are very generic and are used in many places in the application, such as the basic button texts. For specific buttons, we still create translations in components and views.
  • contentNode - contains an entry for each type of content node, such as safety concept or storyboard. Inside such an entry again the keys entity, components and views are allowed.

These rules are enforced by a linter, so make sure to follow them!