Invenio internationalization module.

This module provide features for loading and merging message catalogs. It is built on top of Flask-BabelEx and most external modules should just depend on Flask-BabelEx instead of Invenio-I18N. Only applications in need of loading and merging many message catalogs should integrate this module.

Quick start

First initialize the extension (Flask-BabelEx is also automatically initialized by the extension):

>>> from flask import Flask
>>> from flask_babelex import lazy_gettext as _
>>> app = Flask('myapp')
>>> app.config['I18N_LANGUAGES'] = [('cs', _('Czech')), ('da', _('Danish'))]
>>> from invenio_i18n import InvenioI18N
>>> i18n = InvenioI18N(app)

You can now use the Flask-BabelEx localization features:

>>> from flask_babelex import format_number
>>> with app.test_request_context(headers=[('Accept-Language', 'en')]):
...     format_number(10.1) == '10.1'
>>> with app.test_request_context(headers=[('Accept-Language', 'cs')]):
...     format_number(10.1) == '10,1'

as well as internationalization features:

>>> from flask_babelex import gettext
>>> with app.test_request_context(headers=[('Accept-Language', 'en')]):
...     gettext('Language:') == 'Language:'
>>> with app.test_request_context(headers=[('Accept-Language', 'cs')]):
...     gettext('Language:') == 'Jazyk:'

Marking strings for translation

Following is a short overview on how to mark strings in Python code and templates for translation so that they can be automatically extracted:


You specify translations in Python by importing gettext or lazy_gettext from Flask-BabelEx:

>>> from flask_babelex import gettext as _
>>> _('Test') == 'Test'

For further details and examples see:


In templates you can use either the underscore function:

>>> from flask import render_template_string
>>> with app.app_context():
...     render_template_string("{{_('Test')}}") == 'Test'

or the {% trans %} tag:

>>> with app.app_context():
...     r = render_template_string('{% trans %}Long translation{% endtrans %}')
...     r == 'Long translation'

For further details and examples see:


There is also simple integration for Angular application using Angular-Gettext library. First, you need to mark HTML tags which contain translatable string or expression.

<a href="/" translate>Hello {{name}}</a>

For further details see:


This section only gives a very quick introduction into custom context variables and filters.


The current_i18n global variable is available within Jinja2 templates to give access to an instance of InvenioI18N attached to current application context.

>>> with app.test_request_context(headers=[('Accept-Language', 'en')]):
...     r = render_template_string('{{ current_i18n.language }}')
...     r == 'en'
>>> with app.test_request_context(headers=[('Accept-Language', 'en')]):
...     r = render_template_string('{{ current_i18n.timezone }}')
...     r == 'UTC'
>>> with app.test_request_context(headers=[('Accept-Language', 'da')]):
...     r = render_template_string('{{ current_i18n.locale }}')
...     r == 'da'


There are several useful filters automatically added to the Jinja2 template context:


Invenio-I18N also provides three templates macros that you can use to render a language selector in templates with:

  • language_selector - Renders a list of links and uses GET requests to change the locale.
  • language_selector_form - Same as above, but uses POST requests to change the locale.
  • language_selector_dropdown - Renders a dropdown with languages and uses a POST request to change the locale.

You use the macros by importing one of them from invenio_i18n/macros/language_selector.html, for instance:

>>> with app.test_request_context():
...     r = render_template_string(
...         '{% from "invenio_i18n/macros/language_selector.html"'
...         '   import language_selector %}'
...         '{{ language_selector() }}'
...     )

Working with Message Catalogs

Babel package contains really good documentation which you should read first:


This part focuses on how to configure Babel extraction for Angular application in custom babel-js.ini file:

[angular_gettext: **/static/templates/**/**.html]

To make message extraction and catalog extraction easier you can add following aliases to setup.cfg (replace ${PACKAGE_PATH} with package path):

extract_messages_js = extract_messages -F babel-js.ini -o \
init_catalog_js = init_catalog -D messages-js --input-file \
update_catalog_js = update_catalog -D messages-js --input-file \

Integration with Transifex service

There is a Python package that provides CLI. You can start by installing Transifex package and check if the tx command is available:

$ pip install transifex-client
$ tx --version

The integration is configured in .tx/config file (replace ${PACKAGE_PATH} and ${PACKAGE_NAME}).

host =

file_filter = ${PACKAGE_PATH}/translations/<lang>/LC_MESSAGES/messages.po
source_file = ${PACKAGE_PATH}/translations/messages.pot
source_lang = en
type = PO

file_filter = ${PACKAGE_PATH}/translations/<lang>/LC_MESSAGES/messages-js.po
source_file = ${PACKAGE_PATH}/translations/messages-js.pot
source_lang = en
type = PO

1. Create message catalog

Start by extracting localizable messages from a collection of source files.

$ python extract_messages
$ python init_catalog -l <lang>

If you have localizable Angular messages run commands with _js suffix too.

$ python extract_messages_js
$ python init_catalog_js -l <lang>

2. Transifex project

Ensure project has been created on Transifex under the inveniosoftware organisation.

3. First push

Push source (.pot) and translations (.po) to Transifex.

$ tx push -s -t


From now on do not edit .po files localy, but only on Transifex.

4. Fetch changes

Pull translations for a single/all language(s) from Transifex.

$ tx pull -l <lang>
$ tx pull -a

Check fetched tranlations, commit changes git commit -a -s -m 'i18n: updates from Transifex' and create pull-request.

5. Update message catalog

When new localizable messages are introduced or changes, the message catalog needs to be extracted again. Then you need to push the source files to Transifex service which will take care about updating catalogs. At the end pull translations for all languages from Transifex and commit the changes.

$ python extract_messages
$ python extract_messages_js
$ tx push -s
$ tx pull -a