Skip to content

Internationalization

Yannick Warnier edited this page Feb 9, 2024 · 7 revisions

For a piece of software as large as Chamilo, internationalization (or "i18n") is always kind of a complex process. As we move forward, we always try to optimize the processes, but this page hopefully will give you the information you need to customize your Chamilo, contribute translations or documentation and understand the way translations are managed in Chamilo, starting from version 2.0.

We will leave out of this document (for now) the internationalization elements that are out of a pure translation context:

  • date formats
  • left-to-right vs right-to-left (ltr vs rtl)

Chamilo software internationalization

Translating Chamilo 2.0

Adding new terms

The process of adding new terms has not been defined for Chamilo 2.0 just yet. We will update this page soon. The current process is to add them at least to translations/messages.en.po. If needed in Vue, then also add the term id (same as in messages.en.po) to assets/locales/en.json and run the commands below to update all languages.

New terms syntax: As tempting as it might be to define a title using caps for all words like this "My Super Duper Title", please refrain from doing so as this is a stylistic feature, not a grammatical requirement of the English language. Use "My super duper title" instead.

Translating a term

If you want to translate a term that exists in English but not yet in your own language, just send us a Pull Request against your language file in /translations/messages.[language].po or open a new issue with the updated file.

Adding a language

To add a newly supported language, open an issue in the "Issues" tab and let us know.

Translating a large set of terms

To translate a large number of terms, use the /translations/main.pot and /translations/messages.[language].po in a Gettext-aware translation software, then send us the modified messages.[language].po file through a new issue, or send it through a Pull Request against the master branch.

Chamilo 2.0

Choosing gettext

In previous versions, we used simple "ini-file" style language files, but this required specialized translation tools which we couldn't support. In version 2.0 and above, we use gettext, which has a larger footprint but allows many practical tools to be used for translations.

Backend translations

Translation files are located in /translations/messages.[language].po and use the Gettext format.

Frontend translations

Chamilo 2.0 uses Vue.js, which deals with many elements of the interface. As such, it needs to be aware of, at least, the navigation elements that will appear in the dynamic menus and permanent pieces of the interface.

These translations are stored in assets/locales/ in the JSON format.

To add a new term to the interface, you would need to:

  • add it to the backend translations (with the corresponding translations)
  • add it to new term to assets/locales/en.json
  • php bin/console chamilo:update_vue_translations

There is a way to avoid adding terms manually, using npx, but we don't use it frequently:

npx vue-i18n-extract report --vueFiles './assets/vue/**/*.?(js|vue)' --languageFiles './assets/locales/en.json'

Use --add to add them to en.json, then launch update_vue_translations to update other languages (this will also complete empty English strings in en.json).

See https://github.com/pixari/vue-i18n-extract

At the pure front-end level, you can also use (in JS) the window.languages variable (an array) to get details on the language IDs, ISO codes and original/english names. In the browser console, type window.languages to get the array.

Self-contained terms

When creating new terms, it is important to consider adding full terms with variables, rather than several partial strings.

Hi Jim,

A very clear example of this is the welcome part of an e-mail. Say you want to say "Hello Jim," as the introduction of an e-mail... The e-mail body itself is likely to be very varied (the welcome message could always be the same, while the body will always change), but the welcome message can be re-used over and over.

However, if we try to analyze this message, we can see there are 4 parts:

  • Hi (an opening word)
  • Jim (the name of the person)
  • , (a comma) (marking the end of the welcome message)
  • a blank line (usually represented by \n in web software)

The first element, then, is that the name will change each time. So we want that name to be a variable. For that, there is a relatively common standard in computer sciences, which is to represent it as %s:

  • % to indicate a special marker
  • s to indicate a string (d can be used for decimal numbers, too, but string works for everything you need in a translated term)

So our non-translated string should say something like Hi %s,\n.

You might think that you could split this string, so you don't have to deal with the name in a "weird" way. so you could possibly rely on the developer and just translate "Hi". The developer would then add (programmatically) the name, the comma, the newline marker.

But there's an issue with that:

  • in Japanese, you would write Jim ^、\n (with a different comma sign and the salutation after the name)
  • in Arabic, you would write ،مرحبا جيم\n (right to left, with the comma on the left but the newline on the right)

This is why we ask all new strings to be self-contained, so that the developer only has to replace the variable (the name) inside the string, and not deal with so many conditionals to deal with all languages.

History/legacy

In the past (versions 1.11 and earlier), we used our own system at https://translate.chamilo.org.

Despite us being thankful to the people who built it (on top of a relatively unstable base of Chamilo LCMS) quickly when we needed it, this system had several flaws which slowed us down in the translation process:

  • lacking subscription process and approval process
  • built for multiple translation files, where we later changed to a one-file structure
  • slow export process (in particular when exporting 60 languages)
  • lack of practical JS features to speed up the process
  • lack of integration with tools (like Google Translate) to help with translations suggestions
  • lack of support for Gettext

Nevermind these issues, this system was used from 2010 (the birth of Chamilo) to 2022 (birth of Chamilo 2.0), so hurray for a system that simply worked.

Chamilo user guides internationalization

The Chamilo documentation is already available in several languages at https://docs.chamilo.org/

If you want to contribute, create an account on Github.com, go to https://github.com/chamilo/docs, click on the "Fork" link on the upper right corner of the page. You will then have a (free) full copy of the documentation available.

If you want to contribute some fixes or some additional pages to an existing language, choose the right Branch (they are relatively well named, choose 2.x for the English version of 2.*, or 2.x-fr for the French version, for example) and start editing. Once you're done, use the "Compare & Pull Request" button and just send it. We will receive your suggestion and lead you through any change we might need from you to accept it.

If you want to contribute a new language, you will have to send us an e-mail at info@chamilo.org to request for the new language to be added, and from which language you'd prefer to translate. We will then create a branch for you and you'll be able to extend from that branch.

Clone this wiki locally