i18n / Translation
Internationalization (i18n) is the process of designing software so that it can support different languages and other regional peculiarities. Currently Kalgan only supports the former, which is based on the crate kalgan_i18n.
Configuring i18n
Firstly, we must add the feature i18n
in Cargo.toml:
...
[dependencies]
kalgan = { version = "0.9.1", features = ["i18n"] }
In Kalgan messages are defined in .yaml files. We can locate these files wherever we want. The only important thing is to tell Kalgan the path of the parent folder. We must set this path in our settings.yaml
. By convention it's recommended to locate our message files inside the folder config/i18n
:
i18n:
language:
default: en
path: config/i18n
Besides, every message file must be located inside the language folder. For example:
project/
Cargo.toml
config/
app/
settings.yaml
i18/
en/
messages_in_english.yaml
...
es/
messages_in_spanish.yaml
...
...
src/
main.rs
...
Creating messages
We can organise the message files up to our needs. We can maintain a single file (not recommended in big applications) or split it in multiple files even subfolders. The file naming is not relevante either.
Regarding the syntax, the content of these messages files must fulfil YAML rules and one more thing: the use of dots in the key name is forbidden. As a workaround we can use hyphen instead or a colon followed by a line break and indent. Variables are also supported and they must be surrounded by curly braces (for example: {my_var}
).
Finally, notice that by convention it's expected to follow a snake_case naming syntax for the key names. For example:
home:
title: My Personal Page
description: My name is {name} and I am {age} years old.
cv:
title: This is my CV
contact:
email_address: myemail@gmail.com
phone_number: 456 678 987
...
Last but not least, while we're developing (environment.is_prod: false
) we must be aware that any change made in these files is taken on the fly, without restarting the app. We just have to reload the browser.
Translating messages
We can translate a message from different components of our app. Whatever method we use, notice that the key name of the message is based on dot notation.
In Rust files
The crate kalgan_i18n supports the method Messages.trans
to generate a translated message by passing the language (that is to say, the parent folder name), the key of the message and the list of variables, if exist.
However, this method is not visible through the framework. For this reason Kalgan offers the service i18n::trans
which in turn calls this function. Even better, we count with the macro trans!
we got with the build script when we launched our app for the first time. Both functions do the same job but the with latter the list of variables is optional.
Find below a couple of examples:
home:
title: My Personal Page
description: My name is {name} and I am {age} years old.
...
let title: String = trans!("en", "home.title"); // generates: "My Personal Page"
let description: String = trans!("en", "home.description", hashmap!("name" => "John".to_string(), "age" => 28.to_string())); // generates: "My name is John and I am 28 years old."
...
Notice that for the sake of readability we're calling the macro hashmap!
in the second example.
In html files
Kalgan offers the built-in filter trans
for Tera template engine to render translated messages in html templates. The variable is the key of the message and the language and rest of variables, if present, are passed as named arguments.
For example (using the same messages than in the previous example):
...
<h1>{{ "home.title"|trans(_lang = "en") }}</h1> <!-- generates: <h1>My Personal Page</h1> -->
<p>{{ "home.description"|trans(_lang = "en", name = "john", age = 28) }}</p> <!-- generates: <p>My name is John and I am 28 years old.</p> -->
...
At the beginning of this chapter we had the parameter i18n.language.default
, which we have ignore so far. This parameter is compulsory and must take one of the language folder names supported by our app.
If we don't pass the parameter _lang
Kalgan will automatically take the default language. Notice that in the following example we get the same result than in the previous one:
...
<h1>{{ "home.title"|trans }}</h1> <!-- generates: <h1>My Personal Page</h1> -->
<p>{{ "home.description"|trans(name = "john", age = 28) }}</p> <!-- generates: <p>My name is John and I am 28 years old.</p> -->
...
i18n support in routes
When working with multiple languages we might need to know the language code related to our routes. For this purpose Kalgan offers the field Route.language
.
Remember the struct Route
is not visible and it's only accesible withing the struct kalgan::http::request::Request
.
For more information regarding the routing system go to Localized Routes (i18n) in the docs.