Last active
April 24, 2020 16:22
-
-
Save ewjoachim/d55d9b7dc55d8120ede3a38fc6cc6f36 to your computer and use it in GitHub Desktop.
Workable gettext
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# workalendar/i18n.py | |
import gettext | |
import collections | |
_ = lambda x: x | |
def get_translation_for_language(language: str) -> gettext.Translations: | |
return gettext.translation("mydomain", "/path/to/translations", [language]) | |
def gettext(message:str) -> str: | |
return translations[get_current_language()].gettext(message) | |
def ngettext(count: int, message: str) -> str: | |
return translations[get_current_language()].ngettext(count, message) | |
def pgettext(context: str, message: str) -> str: | |
# 3.8+ only :o | |
return translations[get_current_language()].pgettext(context, message) | |
... | |
def get_current_language() -> str: | |
# Do some magic: read a module variable or a threadlocal or a ContextVar or whatever. Your business. | |
def set_current_translation(language: str) -> None: | |
# Do some magic: write a module variable or a threadlocal or a ContextVar or whatever. Your business. | |
# a.k.a translation.activate | |
@contextlib.contextmanager | |
def override_language(language: str): | |
prev = get_current_language() | |
set_current_language(language) | |
try: | |
yield | |
finally: | |
set_current_language(prev) | |
translations = collections.defaultdict(get_translation_for_language) | |
# workalendar/elsewhere.py | |
from workalendar.i18n import _, translate | |
holiday_name = _("Pâques") | |
def easter_name(): | |
set_current_language("fr") | |
return gettext(holiday_name) | |
#also works with | |
with translation_override("de"): | |
gettext("Pâques") | |
# now back to french |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# workalendar/i18n.py | |
import gettext | |
import collections | |
_ = lambda x: x | |
def get_translation_for_language(language: str) -> gettext.Translations: | |
return gettext.translation("mydomain", "/path/to/translations", [language]) | |
def translate(language: str, message:str) -> str: | |
return translations[language].gettext(message) | |
def translate_count(language: str, count: int, message: str) -> str: | |
return translations[language].ngettext(count, message) | |
def translate_context(language: str, context: str, message: str) -> str: | |
# 3.8+ only :o | |
return translations[language].pgettext(context, message) | |
translations = collections.defaultdict(get_translation_for_language) | |
# workalendar/elsewhere.py | |
from workalendar.i18n import _, translate | |
holiday_name = _("Pâques") | |
def easter_name(language): | |
return translate(language, holiday_name) | |
# or | |
return translate(language, _("Pâques")) |
too bad for the defaultdict function. the function that's passed as a parameter doesn't accept arguments. I've found a way to make my own factory, though.
One step at a time...
Ah snap what I meant was actually a lru_cache ! If you lru_cache get_translation_for_language, then it would work (and you don't need the translation object anymore)
possibly. I think it'd be too early for caching stuff and such. What I'm trying to do at least (with a bit of success, right now, but it's late and I'm tired) is to get translations when language is known. It worked. I'm glad.
Premature optimisation is the root of all evil.
Hm, I think gettext.translation("mydomain", "/path/to/translations", [language])
is really not meant to be called multiple times...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
note the following:
gettext_lazy
like django, or_()
to be a no-op, what I did here