Internationalization & localization =================================== Internationalization is done at two places: at django level using the framework's tool, and with `vue-i18n `__ for client application (slightly customized). The latest implies that translations are stored/accessed by key on the contrary to Django. .. important:: You must provide translations for all model and fields names, as well as for enums (derivating from Django's ones, as ``IntegerChoices``). This makes them available to the frontend app, using the ``vue-i18n`` management command (and avoids you the pain of duplicating translations). So what do we have here? Lets concentrate on frontend (for backend read the Django manual): - Regular Django translations for the backend; - Thoses translations are made available using ``./manage.py vue-i18n`` (called at application install too). => located in ``ox/static/locales/*/django.js`` - The user can also provide custom translation files. => located in ``app/static/locales/*/{app_label}.js`` Oxylus also provides other translations for frontend app in ``ox/static/locales/*/vue.js``. .. note:: The frontend translation files are stored as javascript objects. This allows translations to be loaded as static files, enabling browser cache and avoiding glitches when application is mounted before translations are fetched. How to provide custom translations for the frontend ................................................... Here is an example of what does it looks like, for example ``my_app/static/locales/en/my_app.js``: .. code-block:: javascript window.__i18n_messages??={}; window.__i18n_messages = { ...window.__i18n_messages, ...{ // ... put translations here "actions.replace": "Replace", "labels.value": "Value|Values", }} Usage ..... Don't use vue-i18n's directly; Use the ``t`` imported from ``@oxylus/ox``: .. code-block:: javascript import { t } from "@oxylus/ox" console.log( t("actions.replace") ) console.log( t("labels.value", 12) ) FIXME ----- Lazy loading is done through the ``ox.useI18n`` composable. It internally call ``vue-i18n``'s homonymous function, and dynamically load the files based on configured locale (using fallback locale if the user selected one has failed). When locale change, the corresponding file will be loaded. A client application only needs to load thoses files once, for example as the ``ox_core`` does through the ``OxApp`` component. Nested *non-SFC* components can use ``vue-i18n``s ``useI18n`` instead of Oxylus' one. Since SFC components can be embedded into another application, they require to load locale file (thus use ``ox_core.useI18n``). Conventions ........... Localization keys are case lowered. They are organized around components and objects. Generated by Oxylus: - ``apps.[label]``: application verbose name; - ``enums.[name].[ATTR]``: enums (IntegerChoices, TextChoices, etc.) - ``fields.[name]``: model field verbose name; - ``model.[name]``: model verbose name (+ plural version); Other conventions: - ``actions.[name]``: action label. - ``actions.[name].confirm``: ask for confirmation. - ``panels.[name]``: panel displayed name (by panel name).. - ``panels.[name].nav``: panel navigation label