Skip to main content

i18n services for libraries and applications

Project description

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.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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

morphi-0.2.0.tar.gz (14.6 kB view details)

Uploaded Source

Built Distribution

morphi-0.2.0-py2.py3-none-any.whl (16.6 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file morphi-0.2.0.tar.gz.

File metadata

  • Download URL: morphi-0.2.0.tar.gz
  • Upload date:
  • Size: 14.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.21.0 setuptools/42.0.2 requests-toolbelt/0.9.1 tqdm/4.28.1 CPython/3.6.9

File hashes

Hashes for morphi-0.2.0.tar.gz
Algorithm Hash digest
SHA256 5b534dabe9d10618373b4764bdb7c75b37628fd3423059f84a2b1e57fb887f06
MD5 f6476a6779e9a810222f0d1eaa33a104
BLAKE2b-256 27ccad5a1a7b56c112a35319543454785eb811b2869e738e6777a6ada6c99a92

See more details on using hashes here.

Provenance

File details

Details for the file morphi-0.2.0-py2.py3-none-any.whl.

File metadata

  • Download URL: morphi-0.2.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 16.6 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.21.0 setuptools/42.0.2 requests-toolbelt/0.9.1 tqdm/4.28.1 CPython/3.6.9

File hashes

Hashes for morphi-0.2.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 8815a1ccde669f0cd3fd812a1b505b06399dde4471faf3ba1f662048dcb75179
MD5 d75924f4798c6e1571ede8b4a3667e4c
BLAKE2b-256 2bb0bedd2ec1568a7ebbeb0c0ab164d2e1f538daa28f2b772a37f85c867d174a

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page