invenio-i18n 3.5.0
Invenio internationalization (I18N) module.
License: MIT
Requires Python: >=3.9
Keywords: invenio internationalization i18n localization l10n

..
    This file is part of Invenio.
    Copyright (C) 2015-2018 CERN.

    Invenio is free software; you can redistribute it and/or modify it
    under the terms of the MIT License; see LICENSE file for more details.

==============
 Invenio-I18N
==============

.. image:: https://img.shields.io/github/license/inveniosoftware/invenio-i18n.svg
        :target: https://github.com/inveniosoftware/invenio-i18n/blob/master/LICENSE

.. image:: https://github.com/inveniosoftware/invenio-i18n/workflows/CI/badge.svg
        :target: https://github.com/inveniosoftware/invenio-i18n/actions

.. image:: https://img.shields.io/coveralls/inveniosoftware/invenio-i18n.svg
        :target: https://coveralls.io/r/inveniosoftware/invenio-i18n

.. image:: https://img.shields.io/pypi/v/invenio-i18n.svg
        :target: https://pypi.org/pypi/invenio-i18n

**Invenio-I18N** provides the internationalization layer for InvenioRDM and other Invenio/Flask applications. It integrates the Babel/Flask-Babel stack, merges translation catalogs from multiple sources, exposes safe language-switch routes, and includes CLI tools to fetch from Transifex and distribute i18next-ready JSON for front-end use.

Features
--------
- Load and merge message catalogs from various locations.
- Robust user-locale detection.
- Secure views/endpoints for changing the active locale.
- Jinja2 macros and filters for i18n in templates.
- Fetch from Transifex, read PO files, and convert to/from ``i18next`` JSON for the browser.
- Further documentation: https://invenio-i18n.readthedocs.io/

What it provides
----------------
- **Unified catalogs across locations.** Merge translations from your app, entry-point packages, optional bundles, and extra paths. The multi-directory domain (via ``I18N_TRANSLATIONS_PATHS``) keeps translations modular per feature while rendering as a single catalog.
- **Sensible locale selection.** Language is chosen in this order: **session → user preference → ``Accept-Language`` → default**.
- **Language-switch views.** A small blueprint persists the choice in the session and redirects back safely.
- **Jinja2 helpers.** Macros (e.g., a language selector) and filters such as ``language_name`` plus timezone utilities.
- **Lazy strings.** ``lazy_gettext()`` returns ``LazyString`` objects that resolve at render time—ideal for constants and form labels.
- **Front-end compatibility.** Convert PO catalogs to **i18next-style JSON** or consume i18next JSON directly. Bundled Webpack entries ship minimal JS helpers for the selector; wire JSON into i18next with React, Angular, or plain JS.

How it fits together (high level)
---------------------------------
- **Babel / Flask-Babel** supply gettext, pluralization, and locale-aware formatting.
- **Merged “multidir” domain** overlays catalogs from multiple directories; later sources override earlier ones so apps can override package defaults.
- **Jinja** renders templates/macros for the language selector and localized UI.
- **i18n blueprint** handles ``/lang`` (or your configured path) to set the session language and redirect back.

CLI commands
------------
- **Fetch from Transifex → unified JSON**

  .. code-block:: bash

      invenio i18n fetch-from-transifex \
        -t <TRANSIFEX_TOKEN> -l "en,tr,de" -o js_translations/

  Pulls PO resources from Transifex, maps plurals, and writes **per-language unified i18next JSON**.

- **Distribute JSON back to packages**

  .. code-block:: bash

      invenio i18n distribute-js-translations -i js_translations/

  Splits each unified language file into **per-package** ``translations.json`` under the correct asset paths.

Key configuration (``config.py``)
---------------------------------
- ``I18N_LANGUAGES`` — available languages, e.g. ``[("en","English"),("tr","Türkçe")]``.
- ``I18N_SET_LANGUAGE_URL`` — base URL for the language-switch routes (e.g., ``"/lang"``).
- ``I18N_DEFAULT_REDIRECT_ENDPOINT`` — fallback endpoint after switching.
- ``I18N_SESSION_KEY`` — session key storing the chosen language (default: ``"language"``).
- ``I18N_USER_LANG_ATTR`` — user model attribute for a saved preference (e.g., ``"preferred_language"``).
- ``I18N_TRANSLATIONS_PATHS`` — extra filesystem paths to include in the merged domain.
- ``I18N_JS_DISTR_EXCEPTIONAL_PACKAGE_MAP`` — webpack-entry → package name fixes.
- ``I18N_TRANSIFEX_JS_RESOURCES_MAP`` — maps Transifex resources to packages for JS translations.

Typical locale selection order: **session → user profile → ``Accept-Language`` → ``BABEL_DEFAULT_LOCALE``**.

Minimal setup
-------------

.. code-block:: python

    from flask import Flask
    from invenio_i18n import InvenioI18N
    from invenio_i18n.views import create_blueprint_from_app

    app = Flask(__name__)
    app.config.update(
        SECRET_KEY="dev",
        BABEL_DEFAULT_LOCALE="en",
        BABEL_DEFAULT_TIMEZONE="UTC",
        I18N_LANGUAGES=[("en", "English"), ("tr", "Türkçe")],
        I18N_SET_LANGUAGE_URL="/lang",            # enables the routes
        I18N_USER_LANG_ATTR="preferred_language", # if your User has it
    )

    InvenioI18N(app)                                    # init extension
    app.register_blueprint(create_blueprint_from_app(app))  # language routes

Installation
------------

Available on PyPI:

.. code-block:: bash

    pip install invenio-i18n

..
    This file is part of Invenio.
    Copyright (C) 2015-2018 CERN.
    Copyright (C) 2024-2026 Graz University of Technology.
    Copyright (C) 2025 KTH Royal Institute of Technology.

    Invenio is free software; you can redistribute it and/or modify it
    under the terms of the MIT License; see LICENSE file for more details.

Changes
=======

Version v3.5.0 (released 2026-01-27)

- chore(black): update formatting to >= 26.0
- feat(i18n): improve type hints, add fuzzy tests and module docs
- feat: add cli command to update fuzzy trns and refactor
- feat(i18n): add translation collection/validation service and update CLI
- feat: Update README.rst

Version v3.4.3 (released 2025-10-21)

- i18n: pulled translations

Version v3.4.2 (released 2025-07-22)

- fix(actions): babel compile step missing

Version v3.4.1 (released 2025-07-22)

- fix(babel): migration gone wrong

Version v3.4.0 (released 2025-07-17)

- i18n: pulled translations
- fix(action): commit msg needs whitespace after colon

Version v3.3.0 (released 2025-07-14)

- chores: replaced importlib_xyz with importlib

Version 3.2.0 (released 2025-07-01)

- fix: pkg_resources DeprecationWarning

Version 3.1.0 (released 2025-05-20)

- cli: add command to fetch translation from tansifex
- cli: add command to distribute react translation to packages
- fix: setuptools require underscores instead of dashes

Version 3.0.0 (released 2024-12-02)

- setup: update dependencies

Version 2.2.0 (released 2024-11-28)

- setup: upper pin packages
- fix: tests by pin pytz
- fix: my-site not overriding packages
- ext: add bundle entrypoint
- github: update reusable workflows

Version 2.1.2 (released 2024-08-05)

- fix BABEL_DEFAULT_LOCALE overridability

Version 2.1.1 (released 2023-11-10)

- semantic-ui: Update dependency restriction to be compatible with react-searchkit

Version 2.1.0 (released 2023-07-12)

- add method to check if locale is available

Version 2.0.0 (released 2023-02-27)

- Remove deprecated flask-babelex
- Expose LazyString, gettext from flask_babel to invenio
- Fix get_locale in cli (without request context)
- Replace set_locale with flask_babel.set_locale
- Use Multidomain translation in flask_babel context

Version 1.3.3 (released 2022-11-18)

- Adds translations
- Updates invenio dependencies
- refactors CI tests

Version 1.3.2 (released 2022-03-30)

- Adds support for Flask v2.1

Version 1.3.1 (released 2021-10-06)

- Fixes issue with language selector button not disabling the currently
  selected field.

Version 1.3.0 (released 2020-12-07)

- Integrates Semantic-UI templates and assets.
- Removes webassets-based bundles.
- Adds InvenioI18N extransion to the API level applications.

Version 1.2.0 (released 2020-03-06)

- Bumps Flask-BabelEx support latest Flask/Werkzeug.
- Replaces Flask dependency with ``invenio-base``.

Version 1.1.1 (released 2018-12-12)

- Fix an incorrect JS import.

Version 1.1.0 (released 2018-11-06)

- Introduce webpack support.

Version 1.0.0 (released 2018-03-23)

- Initial public release.