www.hubleto.eu Reddit User Guide Stack Overflow LinkedIn Report an issue

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

  1. 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 as t(context:inner; English text).
  2. 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.
  3. Fill in the translations in lang/<language>/<context>.json.
  4. Turn debugTranslations off.

Adding a language

  1. Create the folder lang/<code>/ and copy the files of an existing language.
  2. Translate the values.
  3. Add the language to availableLanguages in the configuration (or to User::ENUM_LANGUAGES for 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:

Describe the second option in community-core-patches.md so that a loader of Lang/ folders can be added to the core.

Related pages