Package: pyi18n-v2
PyI18nPyI18n is a simple and easy to use internationalization library for Python, inspired by Ruby i18n.Documentation available athttps://sectasy0.github.io/pyi18n.InstallationYou can install PyI18n via pip:pipinstallpyi18n-v2Getting StartedA few motivating and useful examples of how pyi18n can be used.To use PyI18n in your application, you will first need to create a locales folder in the root directory of your project. Within this folder, you can create locale files in the format of your choice (e.g. YAML, JSON).For example:$mkdir-pmy_app/locales
$touchmy_app/locales/en.yml
$touchmy_app/locales/pl.yml
$touchmy_app/locales/de.ymlYou can then create an instance of the PyI18n class, passing in the desired languages and, optionally, a custom locales directory.frompyi18nimportPyI18n# default load_path is locales/# you can change this path by specifying load_path parameteri18n=PyI18n(("en","pl","de","jp"),load_path="translations/")_:callable=i18n.gettextprint(_("en","hello.hello_user",user="John"))#> Hello John!print(_("pl","hello.hello_user",user="John"))#> Witaj John!print(_("de","hello.hello_user",user="John"))#> Hallo John!print(_("jp","hello.hello_user",user="ジョンさん"))#> こんにちは、ジョンさん！NamespacesPyI18n supports namespaces, which allows you to organize your translations into separate groups.To use PyI18n with namespaces, you need to define the loader object yourself. Here's an example:frompyi18n.loadersimportPyI18nYamlLoaderfrompyi18nimportPyI18nif__name__=="__main__":loader:PyI18nYamlLoader=PyI18nYamlLoader('locales/',namespaced=True)pyi18n:PyI18n=PyI18n(('en_US','de_DE'),loader=loader)In this example, we create an instance of the PyI18nYamlLoader class with the namespaced parameter set to True. This tells the loader to look for namespaced locales in separate folders instead of one single file for one locale.Here's an example of the expected file structure for the locales:locales
    en_US
        common.yml
        analysis.yml
    de_DE
        common.yml
        analysis.ymlTo get a key that is located in the common namespace, you should use the dot notation in your translation call:_(locale,'common.greetings')Integrate pyi18n with Django projectTo integrate pyi18n into your Django project, you will need to first add a locale field to your user model class. This field will store the user's preferred language, which will be used to retrieve the appropriate translations from the locales directory.Next, you will need to configure pyi18n in your settings.py file by creating an instance of the PyI18n class and specifying the available languages. You can also create a gettext function for ease of use.In your views, you can then use the gettext function to retrieve translations based on the user's preferred language. To use translations in templates, you will need to create a custom template tag that utilizes the gettext function.settings.pyfrompyi18nimportPyI18ni18n:PyI18n=PyI18n(['pl','en'])_:callable=i18n.gettextviews.pyfrommysite.settingsimport_defindex(request):translated:str=_(request.user.locale,'hello',name="John")returnHttpResponse(f"This is an example view.{translated}")register template tagfromdjangoimporttemplatefrommysite.settingsimport_register=template.Library()@register.simple_tagdeftranslate(locale:str,path:str,**kwargs):return_(locale,path,**kwargs)usage in templatesNOTE:Wrap this tag inside jinja2 special characterstranslaterequest.current_user.locale,"hello",name="John"That's it, you have now successfully installed and configured PyI18n for your project. You can now use the provided gettext function to easily retrieve translations based on the user's preferred language. Additionally, you can use the provided template tag to easily retrieve translations in your templates. And if you need to use custom loaders you can use the PyI18nBaseLoader to create your own loaders.Creating custom loader classTo create custom locale loader you have to create a class which will inherit from PyI18nBaseLoader and overrideloadmethod with all required parameters (see below). You can see an example of custom locale loader inexamples/custom_xml_loader.py.frompyi18n.loadersimportPyI18nBaseLoaderclassMyCustomLoader(PyI18nBaseLoader):defload(self,locales:tuple,load_path:str):# load_path is the path where your loader will look for locales files# locales is a tuple of locales which will be loaded# return a dictionary with locale data...yourcustomloaderlogic...return{}Then pass your custom loader to PyI18n class.frompyi18n.loadersimportPyI18nBaseLoaderclassMyCustomLoader(PyI18nBaseLoader):defload(self,locales:tuple,load_path:str):# load_path is the path where your loader will look for locales files# locales is a tuple of locales which will be loaded...yourcustomloaderlogic...# have to return a dictionaryreturn{}# don't use load_path in `PyI18n` constructor, if not using default yaml loaderif__name__=="__main__":load_path:str="locales/"loader:PyI18nBaseLoader=MyCustomLoader(load_path=load_path)i18n:PyI18n=PyI18n(("en",),loader=loader)_:callable=i18n.gettextprint(_("en","hello.hello_user",user="John"))#> Hello John!TasksTasks usage$pyi18n-tasks
usage:pyi18n-tasks[-h][-pPATH]normalize
pyi18n-tasks:error:thefollowingargumentsarerequired:normalizeNormalizationNormalization process will sort locales alphabetically. The default normalization path islocales/, you can change it by passing-pargument.$pyi18n-tasksnormalize$pyi18n-tasksnormalize-pmy_app/locales/Run testspython3tests/run_tests.pyFor any questions and suggestions or bugs please create an issue.LimitationsNormalization task will not work for custom loader classes except xml, cause it's based on loader type field ( If you have an idea how to solve this differently please open the issue with a description ), if you need that use one of build in loaders or user XML loader from example.RoadmapSee issues, If I have enough time and come up with a good idea on how this package can be improved, I'll post it there, along with tip.Release HistoryRelease History available athttps://sectasy0.github.io/pyi18n/home/release-history/.ContributingFork it (https://github.com/sectasy0/pyi18n)Create your feature branch (git checkout -b feature/fooBar)Commit your changes (git commit -am 'feat: Add some fooBar')Push to the branch (git push origin feature/fooBar)Create a new Pull Request