Skip to main content

Translatable text for applications and libraries.

What is morphi?

morphi was born out of the need to create a distributable library with internally-localized text. Although there are several existing packages which deal with translatable text, they all seem to focus on standalone applications; there seems to be very little available for working with messages that are distributed along with a packaged library.

Foundations

morphi is built on ideas gleaned from the following:

  • the built-in gettext module

  • Babel

Translation

The morphi module provides utilities for loading gettext-compatible translators from either the local filesystem or directly from a package. The default finder will first attempt to locate the messages files in the local filesystem (allowing messages to be overridden on a particular system), but, if a package name is given, will then automatically search the package for the messages files. This allows a library to store default translation messages within the library package itself, and still have those messages be successfully loaded at runtime.

The morphi module is primarily built around the Babel package, with speaklater used for lazy lookups.

Message management

As the morphi module is built on Babel, the standard distutils commands provided by Babel are available, and exposed to downstream use. As such, the standard extract_messages, init_catalog, update_catalog, and compile_catalog commands are all present and work as described in the Babel documentation.

In addition to the standard Babel distutils commands, an additional compile_json command has been added. The compile_json command will compile the messages into a JSON file compatible with the gettext.js javascript library.

Using translations within a library

The easiest way to use the translations is to utilize the Manager class, which encapsulates the lookups and gettext methods, and which provides a way of loading a new messages file after instantiation (allowing the language to be changed after initialization).

As an example, let’s say you’re creating a translation-enabled library named ‘mylib’. The following might be used to initialize and load the translations for use. Details about the “locales registry” can be found below.

# import the translation library
from morphi.messages import Manager
from morphi.registry import default_registry

# instantiate the translations manager
translation_manager = Manager(package_name='mylib')

# register the manager with the default locales registry
default_registry.subscribe(translation_manager)

# initialize shorter names for the gettext functions
gettext = translation_manager.gettext
lazy_gettext = translation_manager.lazy_gettext
lazy_ngettext = translation_manager.lazy_ngettext
ngettext = translation_manager.ngettext

Note that, in general, this code should be executed only a single time for a given package. It is recommended that this code be added to an extensions.py or similar file, from which the gettext functions can be loaded as singletons.

from mylib.extensions import gettext as _

print(_('My translatable text'))

Format variables

The gettext functions all permit additional named parameters, to be used in formatting the translated string. The library currently supports new-style .format type formatting.

print(_('Hello, {name}!', name='World'))

Locales Registry

Particularly when being used with package-specific translations, the Manager will need to be able to be notified when the application’s language settings (particularly the locales) are changed, so that the correct messages can be loaded and displayed. In order to simplify this notification, morphi.registry.Registry (with a default singleton registry named default_registry) can be used. Managers can then be subscribed or unsubscribed to the registry, which will then notify all managers when the locale information has changed.

from morphi.registry import default_registry as locales_registry

locales_registry.locales = 'es'

Typically, a manager should be registered with the registry immediately after it has been instantiated.

Jinja Environment

If using Jinja templates, the Jinja environment should be initialized to add the translation functions.

from morphi.helpers.jinja import configure_jinja_environment

configure_jinja_environment(app.jinja_env, manager)
{{ _('Hello, world!') }}

JavaScript translations

As mentioned above, a compile_json distutils command is added by the library, which will compile the messages to a messages.js-compatible JSON file. The library can be initialized and used as follows

<script src="{{url_for('mylib.static', filename='gettext.min.js')}}"></script>
<script>
    var i18n = window.i18n({});
    window._ = function(msgid, domain) {
        return i18n.dcnpgettext.apply(
            i18n,
            [domain, undefined, msgid, undefined, undefined].concat(
                Array.prototype.slice.call(arguments, 1)
            )
        );
    };
    {% set json_filename = find_mo_filename(package_name='mylib',
                                            extension='json',
                                            localedir='static/i18n') %}
    {% if json_filename %}
        {# strip off the leading 'static/' portion of the filename #}
        {% set json_filename = json_filename[7:] %}
    $.getJSON(
        '{{ url_for("mylib.static", filename=json_filename) }}'
    ).then(function (result) {
        i18n.loadJSON(result, 'mylib');
    });
    {% endif %}
</script>

. . .

<p>_('Hello, world!', 'mylib')</p>

Note the presence of the find_mo_filename function; this function is made available by calling the configure_jinja_environment manager method as described above.

Installation

morphi can be installed via pip:

pip install morphi

To install for development, simply add the develop tag:

pip install morphi[develop]

Development

Testing

Testing currently uses pytest:

pytest morphi

Changelog

0.3.2 released 2025-07-10

  • fix regression for consumers using setup.py (b7eeb2a)

0.3.1 released 2025-04-11

  • support pyproject.toml apps (b32aa95)

0.3.0 released 2024-12-18

  • fix deprecated pkg_resources usage (de64dba)

0.2.2 released 2023-03-02

  • include pytz, since babel no longer does by default (4beab17)

0.2.1 released 2022-10-26

  • update package setup and CI, resolve pkg_resources warning (cd0f750)

0.2.0 released 2020-05-12

  • use pyp for releasing (c4cf37f)

  • support Babel 2.7+ and provide a CI helper method (bc0ef3f)

0.1.2 released 2019-02-11

  • Fix errors when using invalid user-supplied resource paths with the resource loader

0.1.1 released 2018-09-20

  • Fix pkg_resources support under pyinstaller

0.1.0 released 2018-08-22

  • Add initial translations implementation

Release files for morphi 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for morphi 0.3.2
File Size Uploaded
morphi-0.3.2.tar.gz 18.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for morphi 0.3.2
File Interpreter ABI Platform
morphi-0.3.2-py2.py3-none-any.whl Python 3, Python 2 none any Details

Total release size: 36.3 kB

Release files / morphi-0.3.2.tar.gz

Download URL morphi-0.3.2.tar.gz
Size 18.4 kB
Tags Source
SHA-256 checksum
How to use checksums
bda9d1f12045d694ddf204b1fc44e43caf0ab792a599b818be8188e3b781c08a
BLAKE2b-256 checksum
How to use checksums
76ea03783147fa3321b4e7d1aa2950c578f0cb4188b985af21e0a16fb37db37f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.0 CPython/3.9.23

Release files / morphi-0.3.2-py2.py3-none-any.whl

Download URL morphi-0.3.2-py2.py3-none-any.whl
Size 17.8 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
281fe08463eda365fe257c859b2c892eb6b7ecec77255a16cff002ae21ee0b08
BLAKE2b-256 checksum
How to use checksums
13701adea3a3ea81fe5f6ddbd4982bd658194b983b0087abc977aace03c7b5ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.0 CPython/3.9.23

Release history Release notifications | RSS feed

This release

0.3.2 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page