Themes built on the Twig templating engine are now deprecated and require migration to Vitrin to ensure continued support and compatibility with Zid.
jinja2.ext.i18n
).po
files map those source strings to translated text. Jinja’s jinja2.ext.i18n
extension makes this flow natural and ergonomic..po
file really is.po
file is a human-editable catalog that pairs each source string (msgid
) with its translation (msgstr
). Translators also see comments, fuzzy flags, and plural rules, and they use established tools to manage quality. For runtime speed, .po
files are compiled into binary .mo
files—no app logic required.msgid "Add to cart"
msgstr "أضف إلى السلة"
# Plural example with a numeric placeholder
msgid "%(n)s item"
msgid_plural "%(n)s items"
msgstr[0] "لا عناصر"
msgstr[1] "عنصر واحد"
msgstr[2] "عنصران"
msgstr[3] "%(n)s عناصر"
msgstr[4] "%(n)s عنصرًا"
msgstr[5] "%(n)s عنصر"
msgstr[index]
is chosen.{{ _("Add to cart") }}
{% trans count=n %}{{ count }} item{% pluralize %}{{ count }} items{% endtrans %}
{% trans store=store_name %}Welcome to {{ store }}!{% endtrans %}
{# Contextual disambiguation: same English, different meaning #}
{{ pgettext("button", "Open") }}
{{ pgettext("verb", "Open") }}
{% trans %}
bindings.
babel.cfg
to make Jinja extraction work:
locals.*
approachlocals.*
to templates and accessed keys such as {{ locals.add_to_cart }}
. That “dictionary of messages” works in a pinch, but it shifts localization responsibilities onto application code and template authors:open_button
, open_action
) and policing consistency manually.ar-SA → ar → en
), and missing keys could silently break or degrade UX.locals.*
to Gettext{% trans %}
and ngettext
to handle variables and plurals.{{ locals.add_to_cart }}
{{ _("Add to cart") }}
{{ n == 1 ? locals.one_item : locals.many_items }}
{% trans count=n %}{{ count }} item{% pluralize %}{{ count }} items{% endtrans %}
{{ locals.welcome }} {{ store_name }}
{% trans store=store.name %}Welcome to {{ store }}!{% endtrans %}
{{ locals.open_button }}
{{ locals.open_action }}
{{ pgettext("button", "Open") }}
{{ pgettext("action", "Open") }}
.mo
files are compiled..po
files. With those habits, Gettext + Jinja gives you a clean, scalable, and translator-friendly localization system—far more robust than passing a bespoke locals.*
mapping into your views.