masonite
masonite copied to clipboard
RFC: add translations handling
I like to implement a translation handling using gettext, here is what I did:
given a template with translations e.g. in welcome.html
{{ _("Translation") }}
create locales path
mkdir -p locales/de/LC_MESSAGES/
create a po file base.po in that locales path
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-08-22 08:36+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "Translation"
msgstr "Übersetzung"
generate a mo file from po file (gnu gettext)
cd locales/de/LC_MESSAGES/
msgfmt base.po
final tree
|-- locales
| `-- de
| `-- LC_MESSAGES
| |-- base.mo
| `-- base.po
created a config/locale.py with available translations:
LANGUAGES = ["en", "de"]
DEFAULT_LANUGAGE = "en"
created a language middleware to parse the browser header of accepted languages and compare with available translations list from a created config locale.py
import os
from masonite.facades import Config
from masonite.middleware import Middleware
def parseAcceptLanguage(acceptLanguage):
languages = acceptLanguage.split(",")
locale_q_pairs = []
for language in languages:
if language.split(";")[0] == language:
# no q => q = 1
locale_q_pairs.append((language.strip(), "1"))
else:
locale = language.split(";")[0].strip()
q = language.split(";")[1].split("=")[1]
locale_q_pairs.append((locale, q))
return locale_q_pairs
class LanguageMiddleware(Middleware):
def before(self, request, response):
languages = Config.get("locale.languages")
accpeted_languages = parseAcceptLanguage(request.header("Accept-Language"))
for accpeted_language in accpeted_languages:
al, q = accpeted_language
if al in languages:
language = al
break
else:
language = Config.get("locale.default_language")
os.environ["LANGUAGE"] = language
return request
def after(self, request, response):
return request
Things missing:
- ~change language based on header accept language?~
- test for the path locale/ is probably not ideal, enable/disable using conf?