{% blocktranslate with email=branding.support_email %}Email: {{ email }}{% endblocktranslate %}
.. code-block:: python from django.utils.translation import gettext as _ error_message = _("Invalid login attempt. Unknown user %(email)s") % {"email": email} .. code-block:: tsx import { gettext, interpolate, interpolateNodes, ngettext } from "@smarter/common"; interpolate(gettext("Failed to load budgets (%(status)s)."), { status: response.status }); interpolate(ngettext("%(count)s path", "%(count)s paths", count), { count }); // a React element inside a sentence interpolateNodes(gettext("Rename secret %(name)s."), { name: {secret.name} }); .. code-block:: javascript // smarter/static/js Swal.fire({ text: gettext("Copied API key to the clipboard."), confirmButtonText: gettext("Ok, got it!") }); Some rules keep the catalogs translatable: - **Don't build sentences from pieces.** ``"Successfully " + verb + "d"`` can't be translated. Write one message for each case, as the list pages' ``actionMessages()`` does for clone, rename and delete. - **Use ngettext() for counts**, never a conditional ``"s"``. Languages have different plural rules. - **Use pgettext() when one English word has two meanings**, e.g. a verb and a noun. - **Explain anything ambiguous** with a comment that begins with ``Translators:``, on the line before the call, or before the ``{% translate %}`` tag. It is copied into the ``.po`` file. - **Don't translate** resource kinds in code, manifest field names, commands, product names, log messages, or errors that only developers see, such as a missing attribute in ``main.tsx``. Updating the Catalogs --------------------- After changing marked text, regenerate the catalogs, with the containers running the current code: .. code-block:: console make build && make run # in another terminal, or in the background make i18n-messages ``make i18n-messages`` runs ``npm run i18n:extract``, then the ``update_console_messages`` management command in the ``smarter-app`` container, which runs ``makemessages`` for both domains and every language in ``settings.LANGUAGES``, keeping the translations already in the ``.po`` files, then ``compilemessages``. It copies the catalogs back to the host. Commit the changed ``.po`` files and ``messages.js``. ``make i18n-messages LANGUAGE=es`` updates one language. Adding a Language ----------------- 1. Add the language to ``LANGUAGES`` in ``smarter/smarter/settings/base.py``, e.g. ``("es", "Spanish")``. 2. Add its `date-fns