Translations¶
Use Slint’s translation infrastructure to make your application available in different languages.
Complete the following steps to translate your application:
Identify all user visible strings that need to be translated and annotate them with the
@tr()
macro.Extract annotated strings using the
slint-tr-extractor
tool and generate.pot
files.Use a third-party tool to translate the strings into a target language, as
.po
files.Use gettext’s
msgfmt
tool to convert.po
files into run-time loadable.mo
files.Use Slint’s API to select and load
.mo
files at run-time, based on the user’s locale settings. At this point, all strings marked for translation will automatically be rendered in the target language.
Annotating Translatable Strings¶
Use the @tr
macro in .slint
files to mark that a string is meant to be translated. This macro
will take care of both the translation and the formatting, by replacing {}
placeholders.
The first argument must be a plain string literal, followed by the arguments:
export component Example {
property <string> name;
Text {
text: @tr("Hello, {}", name);
}
}
Formatting¶
The @tr
macro replaces each {}
placeholder in the string marked for translation with the corresponding argument.
It’s also possible to re-order the arguments using {0}
, {1}
, and so on. Translators can use ordered
placeholders even if the original string did not.
The literal characters {
and }
may be included in a string by preceding them with the same character.
For example, the {
character is escaped with {{
and the }
character is escaped with }}
.
Plurals¶
Use plural formatting when the translation of text involving a variable number of elements should change depending on whether there is a single element or multiple.
Given count
and an expression that represents the count of something, form the plural with the |
and %
symbols like so:
@tr("I have {n} item" | "I have {n} items" % count)
.
Use {n}
in the format string to access the expression after the %
.
export component Example inherits Text {
in property <int> score;
in property <int> name;
text: @tr("Hello {0}, you have one point" | "Hello {0}, you have {n} point" % score, name);
}
Context¶
Disambiguate translations for strings with the same source text but different contextual meanings by adding a context
to the @tr(...)
macro using the "..." =>
syntax.
Use the context to provide additional context information to translators, ensuring accurate and contextually appropriate translations.
The context must be a plain string literal and it appears as msgctx
in the .pot
files. If not specified, the context defaults
to the name of the surrounding component.
export component MenuItem {
property <string> name : @tr("Name" => "Default Name"); // Default: `MenuItem` will be the context.
property <string> tooltip : @tr("ToolTip" => "ToolTip for {}", name); // Specified: The context will be `ToolTip`.
}
Extract Translatable Strings¶
Use the slint-tr-extractor
tool to generate a .pot
file from .slint
files.
You can run it like so:
find -name \*.slint | xargs slint-tr-extractor -o MY_PROJECT.pot
This will create a file called MY_PROJECT.pot
. Replace MY_PROJECT with your actual project name.
To learn how the project name affects the lookup of translations, see the sections below.
.pot
files are Gettext template files.
Translate the Strings¶
Start a new translation by creating a .po
file from a .pot
file. Both file formats are identical.
You can either copy the file manually or use a tool like Gettext’s msginit
to start a new .po
file.
The .po
file will contain the strings in a target language.
.po
and .pot
files are plain text files, that you can edit with a text editor. We recommend
using a dedicated translation tool for working with them, such as the following:
Convert .po
Files to .mo
Files¶
The human readable .po
files need to be converted into machine-friendly .mo
files, a binary representation
that is very efficient to read.
Use Gettext’s msgfmt
command line tool to convert .po
files to .mo
files:
msgfmt translation.po -o translation.mo
Select and Load .mo
Files at Run-Time¶
Slint uses the Gettext library to load translations at run-time. Gettext locates the translation file in the following location: Gettext expects translation files - called message catalogs - to be placed in following directory hierarchy:
dir_name/locale/LC_MESSAGES/domain_name.mo
dir_name
: the base directory that you can choose freely.locale
: The name of the user’s locale for a given target language, such asfr
for French, orde
for German. The locale is typically determined using environment variables that your operating system sets.domain_name
: Selected based on the programming language you’re using Slint with.
For more info, see the Gettext documentation.
Select and Load Translations with Rust¶
First, enable the gettext
feature of the slint
create to gain access to the translations API
and activate run-time translation support.
Next, use the slint::init_translations!
to specify the base location of your .mo
files. This is
the dir_name
in the scheme of the previous section. The .mo
files are expected to be in the
corresponding sub-directories and their file name - domain_name
- must match the package name
in your Cargo.toml
. This is often the same as the crate name.
For example:
slint::init_translations!(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/"));
Suppose your Cargo.toml
contains the following lines and the user’s locale is fr
:
[package]
name = "gallery"
With these settings, Slint will look for gallery.mo
in the lang/fr/LC_MESSAGES/gallery.mo
.
Select and Load Translations with C++¶
First, enable the SLINT_FEATURE_GETTEXT
cmake option when compiling Slint, to gain access to
the translations API and activate run-time translation support.
In C++ applications using cmake, the domain_name
is the CMake target name.
Next, bind the text domain to a path using the standard gettext library.
To do so, add this in your CMakeLists.txt
find_package(Intl)
if(Intl_FOUND)
target_compile_definitions(my_application PRIVATE HAVE_GETTEXT SRC_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
target_link_libraries(my_application PRIVATE Intl::Intl)
endif()
You can then setup the locale and the text domain
#ifdef HAVE_GETTEXT
# include <locale>
# include <libintl.h>
#endif
int main()
{
#ifdef HAVE_GETTEXT
bindtextdomain("my_application", SRC_DIR "/lang/");
std::locale::global(std::locale(""));
#endif
//...
}
Suppose you’re using the above and the user’s locale is set to fr
,
Slint will look for my_application.mo
in the lang/fr/LC_MESSAGES/
directory.
Previewing Translations with slint-viewer
¶
Use slint-viewer
to preview translations when previewing .slint
files:
Enable the
gettext
feature when compilingslint-viewer
.Use the
--translation-domain
andtranslation-dir
command line options to load translations and display them based on the current locale.