Localization
Hubleto is localized in three places: the PHP code, the Twig views and the React components. All three read the same language packs, so a string is translated once.
The practical step-by-step guide for apps is Translations. This page explains how the localization works and how to prepare a new language.
Languages
The user selects the language in the profile, or by opening any URL with ?set-language=sk. The choice is saved in the user's record and in a cookie.
| Code | Language | Language pack in hubleto/erp |
|---|---|---|
en |
English | built in (no pack needed) |
cs |
Czech | yes |
de |
German | yes |
es |
Spanish | yes |
fr |
French | yes |
pl |
Polish | yes |
ro |
Romanian | yes |
sk |
Slovak | yes |
it |
Italian | offered in the language list, but no pack exists yet |
Languages of Hubleto ERP.
The list of languages comes from Hubleto\Erp\Locale::getAvailableLanguages(). The same class formats numbers, dates and currencies (hubleto.locale().formatCurrency(...) in Twig).
English is the source language
Write every text in your code in English. The English text is the key of the dictionary, so there is no English language pack. For another language the text is looked up in the pack; if it is missing, the English text is shown.
Translating in code
| Where | Function | Example |
|---|---|---|
| PHP | $this->translate($string, $vars) |
$this->translate('Price list was not found.') |
| Twig | translate($string, $vars) |
{{ translate('Recent activities') }} |
| React (TSX) | T.translate($string, $vars) |
T.translate('Customer') |
Translation functions.
A variable in the text is written as {{ name }} and passed in $vars. Never build a sentence from translated pieces; translate the whole sentence with variables:
// wrong: the word order differs between languages
$message = $this->translate('Price list') . ' ' . $name . ' ' . $this->translate('expires');
// right
$message = $this->translate('Price list {{ name }} expires on {{ date }}.', [
'name' => $name,
'date' => $date,
]);
Real examples are on every page of the checklist, e.g. FormCustomer.tsx:
apps/Customers/Components/FC/FormCustomer.tsx (excerpt)
title={{fields: ['identifier', 'name'], sub: T.translate('Customer')}}
Language packs
The packs are JSON files in the lang/<language>/ folder of the hubleto/erp package. One file belongs to one translation context: the namespace of the Loader of an app, in lower case with dashes.
| Context / file name | Used by |
|---|---|
hubleto-app-community-customers-loader.json |
Hubleto\App\Community\Customers |
hubleto-app-community-deals-loader.json |
Hubleto\App\Community\Deals |
hubleto-erp-loader.json |
Hubleto\Erp (core, desktop, React UI) |
hubleto-app-custom-carrental-loader.json |
Hubleto\App\Custom\CarRental |
Contexts and files.
Inside a file the strings are grouped by an inner context: the manifest, or the controller or model that uses the string. The key is the English text, the value is the translation:
lang/sk/hubleto-app-community-customers-loader.json (excerpt)
{
"manifest": {
"Customers": "Zákazníci",
"Free customer management and addressbook.": "Bezplatná správa zákazníkov a adresár.",
"Customer Tags": "Značky zákazníkov"
},
"Models\\Customer": {
"Add Customer": "Pridať zákazníka",
"Name": "Názov",
"Street Line 1": "Ulica, riadok č. 1",
"Street Line 2": "Ulica, riadok č. 2",
"Region": "Región",
"City": "Mesto",
"Country": "Krajina",
An empty value means "not translated yet"; the English text is shown.
The workflow for translators
- Turn on the setting
debugTranslations(a configuration value). Untranslated strings are shown as** English text **and strings that are missing in the pack are shown ast(context:inner; English text). - Click through your app. Every missing string is added to the pack of every language (with an empty value), as long as the file of the context already exists.
- Fill in the translations in
lang/<language>/<context>.json. - Turn
debugTranslationsoff.
Adding a language
- Create the folder
lang/<code>/and copy the files of an existing language. - Translate the values.
- Add the language to
availableLanguagesin the configuration (or toUser::ENUM_LANGUAGESfor the profile selector) and add its flag image.
Custom apps
The Translator loads the packs only from the lang/ folder of hubleto/erp. It does not read a Lang/ folder inside an app. Until this is changed in the core, a custom app has two options:
- Ship English only. Write all texts in English and the app works in every language.
- Add a pack
lang/<code>/hubleto-app-custom-<appname>-loader.jsonto theerppackage (for a project: a patch or a fork).
Describe the second option in community-core-patches.md so that a loader of Lang/ folders can be added to the core.
Related pages
- Translations — PHP classes, Twig, React and language packs of apps
- Locale and formatting
