core.i18n

This module provides translation, also known as internationalization – short: i18n.

Project translations must be stored in the datastore. There are only some static translation tables in the viur-core to have some basic ones.

The viur-core’s own “translation” module (routed as _translation) provides an API to manage these translations, for example in the vi-admin.

How to use translations? First, make sure that the languages are configured: .. code-block:: python

from viur.core.config import conf # These are the main languages (for which translated values exist) # that should be available for the project. conf.i18n.available_languages = = [“en”, “de”, “fr”]

# These are some aliases for languages that should use the translated # values of a particular main language, but don’t have their own values. conf.i18n.language_alias_map = {

“at”: “de”, # Austria uses German “ch”: “de”, # Switzerland uses German “be”: “fr”, # Belgian uses France “us”: “en”, # US uses English

}

Now translations can be used

1. In python .. code-block:: python

from viur.core.i18n import translate # Just the translation key, the minimal case print(translate(“translation-key”)) # also provide a default value to use if there’s no value in the datastore # set and a hint to provide some context. print(translate(“translation-key”, “the default value”, “a hint”)) # Use string interpolation with variables print(translate(“hello”, “Hello {{name}}!”, “greeting a user”)(name=current.user.get()[“firstname”]))

2. In jinja .. code-block:: jinja

{# Use the ViUR translation extension, it can be compiled with the template,

caches the translation values and is therefore efficient #}

{% do translate “hello”, “Hello {{name}}!”, “greet a user”, name=”ViUR” %}

{# But in some cases the key or interpolation variables are dynamic and

not available during template compilation. For this you can use the translate function: #}

{{ translate(“hello”, “Hello {{name}}!”, “greet a user”, name=skel[“firstname”]) }}

How to add translations There are two ways to add translations: 1. Manually With the vi-admin. Entries can be added manually by creating a new skeleton and filling in of the key and values.

2. Automatically The add_missing_translations option must be enabled for this. .. code-block:: python

from viur.core.config import conf conf.i18n.add_missing_translations = True

If a translation is now printed and the key is unknown (because someone has just added the related print code), an entry is added in the datastore kind. In addition, the default text and the hint are filled in and the filename and the line from the call from the code are set in the skeleton. This is the recommended way, as ViUR collects all the information you need and you only have to enter the translated values. (3. own way Of course you can create skeletons / entries in the datastore in your project on your own. Just use the TranslateSkel).

Module Contents

Classes

LanguageWrapper

Wrapper-class for a multi-language value.

translate

Translate class which chooses the correct translation according to the request language

TranslationExtension

Default translation extension for jinja2 render.

Functions

initializeTranslations()

Fetches all translations from the datastore and populates the systemTranslations dictionary of this module.

add_missing_translation(key[, hint, default_text, ...])

Add missing translations to datastore

migrate_translation(key)

Migrate entities, if required.

localizedStrfTime(datetimeObj, format)

Provides correct localized names for directives like %a which don't get translated on GAE properly as we can't

Attributes

systemTranslations

Memory storage for translation methods

KINDNAME

Kindname for the translations

localizedDateTime

localizedDate

localizedTime

localizedAbbrevDayNames

localizedDayNames

localizedAbbrevMonthNames

localizedMonthNames

core.i18n.systemTranslations

Memory storage for translation methods

core.i18n.KINDNAME = 'viur-translations'

Kindname for the translations

class core.i18n.LanguageWrapper(languages)

Bases: dict

Wrapper-class for a multi-language value.

It’s a dictionary, allowing accessing each stored language, but can also be used as a string, in which case it tries to guess the correct language. Used by the HTML renderer to provide multi-lang bones values for templates.

Parameters:

languages (list[str] | tuple[str]) – Languages which are set in the bone.

__str__()

Return str(self).

Return type:

str

__bool__()
Return type:

bool

resolve()

Causes this wrapper to evaluate to the best language available for the current request.

Returns:

An item stored inside this instance or the empty string.

Return type:

str

class core.i18n.translate(key, defaultText=None, hint=None, force_lang=None)

Translate class which chooses the correct translation according to the request language

This class is the replacement for the old translate() function provided by ViUR2. This classes __init__ takes the unique translation key (a string usually something like “user.auth_user_password.loginfailed” which uniquely defines this text fragment), a default text that will be used if no translation for this key has been added yet (in the projects default language) and a hint (an optional text that can convey context information for the persons translating these texts - they are not shown to the end-user). This class will resolve its translations upfront, so the actual resolving (by casting this class to string) is fast. This resolves most translation issues with bones, which can now take an instance of this class as it’s description/hints.

Parameters:
  • key (str) – The unique key defining this text fragment. Usually it’s a path/filename and a unique descriptor in that file

  • defaultText (str) –

    The text to use if no translation has been added yet. While optional, it’s recommended to set this, as the key is used

    instead if neither are available.

  • hint (str) – A text only shown to the person translating this text, as the key/defaultText may have different meanings in the target language.

  • force_lang (str) – Use this language instead the one of the request.

__slots__ = ['key', 'defaultText', 'hint', 'translationCache', 'force_lang']
__repr__()

Return repr(self).

Return type:

str

__str__()

Return str(self).

Return type:

str

translate(**kwargs)

Substitute the given kwargs in the translated or default text.

Return type:

str

__call__(**kwargs)

Just an alias for translate

static substitute_vars(value, **kwargs)

Substitute vars in a translation

Variables has to start with two braces ({{), followed by the variable name and end with two braces (}}). Values can be anything, they are cast to string anyway. “Hello {{name}}!” becomes with name=”Bob”: “Hello Bob!”

Parameters:

value (str) –

static merge_alias(translations)

Make sure each aliased language has a value

If an aliased language does not have a value in the translation dict, the value of the main language is copied.

Parameters:

translations (dict[str, str]) –

class core.i18n.TranslationExtension(environment)

Bases: jinja2.ext.Extension

Default translation extension for jinja2 render. Use like {% translate “translationKey”, “defaultText”, “translationHint”, replaceValue1=”replacedText1” %} All except translationKey is optional. translationKey is the same Key supplied to _() before. defaultText will be printed if no translation is available. translationHint is an optional hint for anyone adding a now translation how/where that translation is used. force_lang can be used as a keyword argument (the only allowed way) to force the use of a specific language, not the language of the request.

Parameters:

environment (jinja2.environment.Environment) –

tags
parse(parser)

If any of the tags matched this method is called with the parser as first argument. The token the parser stream is pointing at is the name token that matched. This method has to return one or a list of multiple nodes.

_translate(key, default_text, hint, kwargs, translations, caller)

Perform the actual translation during render

Parameters:
  • key (str) –

  • default_text (str) –

  • hint (str) –

  • kwargs (dict[str, Any]) –

  • translations (dict[str, str]) –

Return type:

str

core.i18n.initializeTranslations()

Fetches all translations from the datastore and populates the systemTranslations dictionary of this module. Currently, the translate-class will resolve using that dictionary; but as we expect projects to grow and accumulate translations that are no longer/not yet used, we plan to made the translation-class fetch it’s translations directly from the datastore, so we don’t have to allocate memory for unused translations.

Return type:

None

core.i18n.add_missing_translation(key, hint=None, default_text=None, filename=None, lineno=None, variables=None)

Add missing translations to datastore

Parameters:
  • key (str) –

  • hint (str | None) –

  • default_text (str | None) –

  • filename (str | None) –

  • lineno (int | None) –

  • variables (list[str]) –

Return type:

None

core.i18n.migrate_translation(key)

Migrate entities, if required.

With viur-core 3.6 translations are now managed as Skeletons and require some changes, which are performed in this method.

Parameters:

key (viur.core.db.Key) –

Return type:

None

core.i18n.localizedDateTime
core.i18n.localizedDate
core.i18n.localizedTime
core.i18n.localizedAbbrevDayNames
core.i18n.localizedDayNames
core.i18n.localizedAbbrevMonthNames
core.i18n.localizedMonthNames
core.i18n.localizedStrfTime(datetimeObj, format)

Provides correct localized names for directives like %a which don’t get translated on GAE properly as we can’t set the locale (for each request). This currently replaces %a, %A, %b, %B, %c, %x and %X.

Parameters:
  • datetimeObj (datetime.datetime) – Datetime-instance to call strftime on

  • format (str) – String containing the Format to apply.

Returns:

Date and time formatted according to format with correct localization

Return type:

str