Skip to content

Instantly share code, notes, and snippets.

@ewjoachim
Last active April 24, 2020 16:22
Show Gist options
  • Save ewjoachim/d55d9b7dc55d8120ede3a38fc6cc6f36 to your computer and use it in GitHub Desktop.
Save ewjoachim/d55d9b7dc55d8120ede3a38fc6cc6f36 to your computer and use it in GitHub Desktop.
Workable gettext
# 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
# 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"))
@ewjoachim
Copy link
Author

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