Gettext (i18n)
Gettext is an i18n tool that is separate from your app's code. The main benefit over other tools is, just as GResource, being integrated with GTK. Gettext apart from basic 1 on 1 translations, is also able to handle plurals and automatically detect the system's language.
You can get the Crystal bindings for it and explore its methods at: https://github.com/GeopJr/gettext.cr.
There are three filetypes associated with it: .pot, .po & .mo. The last one is binary.
Getting Started
Create a
po/folder if you haven't alreadyCreate a
po/LINGUASfile that includes the language codes of the available translations, one per lineCreate a
po/POTFILESfile that includes the paths of the files we should extract strings from (usually all .ui files, metainfo & desktop)Run
xgettextto extract the translatable strings into a.potfile, which acts as a "template" for the other translations:
$ xgettext --files-from=po/POTFILES --output=po/APP_ID.pot- Create a
.pofile for a language usingmsginite.g.:
$ msginit -i po/APP_ID.pot -o po/el.po -l el_GR.utf8Translate the strings found in the newly created
.pofileCreate a binary
.mousingmsgfmte.g.:
$ msgfmt po/el.po -o po/locale/el/LC_MESSAGES/APP_ID.moMove the
po/locale/to/usr/share/locale(not necessary)Add the following to your
prerequisites:
Gettext.setlocale(Gettext::LC::ALL, "")
# The macro allows you to set a custom env var during compile time for the mo location e.g. `MY_APP_LOCALE_LOCATION="./po/locale/"`
Gettext.bindtextdomain("APP_ID", {{env("MY_APP_LOCALE_LOCATION").nil? ? "/usr/share/locale" : env("MY_APP_LOCALE_LOCATION")}})
Gettext.textdomain("APP_ID")- Test it by running it with
LANG="el"
You can also add strings that only exist in code in the .pot (and .po) files and then translate them on demand, for instance:
label = Gtk::Label.new("")
label.text = Gettext.gettext("Hello World")
# LANG="en" => "Hello World"
# LANG="el" => "Γειά σου Κόσμε"Translating .desktop and metainfo files
Translating those files is just as easy, for the sake of not replacing themselves, add the .in extension (APP_ID.dekstop.in & APP_ID.metainfo.xml.in).
TIP
Don't forget to update them in the POTFILES file too.
Now all you have to do is run:
- For the metainfo file:
$ msgfmt --xml --template data/APP_ID.metainfo.xml.in -d "./po" -o data/APP_ID.metainfo.xml- For the .desktop file
$ msgfmt --desktop --template data/APP_ID.desktop.in -d "./po" -o data/APP_ID.desktopINFO
You need to have the language you are testing with, installed (locale -a).
TIP
Remember to add *.mo to your .gitignore.
TIP
Replace APP_ID with your app's ID.