Messages are used to externalize pieces of text in order to be able to provide translations for them. Revel supports message files organized per language, automatic locale look-up, cookie-based overrides and message nesting and arguments.
Glossary
- Locale: a combination of language and region that indicates a user language preference, eg.
en-US
. - Language: the language part of a locale, eg.
en
. Language identifiers are expected to be ISO 639-1 codes. - Region: the region part of a locale, eg.
US
. Region identifiers are expected to be ISO 3166-1 alpha-2 codes.
Implementation Methods
Revel allows you to implement internalization at template, or as embedded messages.
Templates when loading will automatically look for a region specific template first
app/
views/
Index/App.html.en
Index/App.html.fr
...
You can also include templates that will check for regions automatically using the i18ntemplate. This tag acts like a traditional template tag except that it will automatically choose the region based on the ViewArgs passed in. (optionally the region may be specified as the third argument) It can be used on a page like
<p>
Embedded Regional Template Example
{{i18ntemplate "templateName" .}}
</p>
Example Application
The way Revel handles message files and internationalization in general is similar to most other web frameworks out there. For those of you that wish to get
started straight away without going through the specifics, there is a sample application
examples/i18n
which demonstrates the basics.
Configuration
File | Option | Description |
---|---|---|
app.conf
|
i18n.cookie
|
The name of the language cookie. Should always be prefixed with the Revel cookie prefix to avoid cookie name conflicts. |
app.conf
|
i18n.default_language
|
The default locale to use in case no preferred locale could be found. |
app.conf
|
i18n.locale.parameter
|
The name of the parameter to use for switching the current language of the application. The parameter value is checked before other methods to resolve the client locale. |
Message Files
Messages are defined in message files. These files contain the actual text that will be used while rendering the view (or elsewhere in your application if you so desire). When creating new message files, there are a couple of rules to keep in mind:
- All message files should be stored in the
messages/
directory in the application root. - The file extension determines the language of the message file and should be an ISO 639-1 code.
- Message files should be UTF-8 encoded. While this is not a hard requirement, it is best practice.
- Each message file is effectively a goconfig file and supports all goconfig features.
Organizing Message Files
There are no restrictions on message file names; a message file name can be anything as long as it has a valid extention. There is also no restriction on the amount
of files per language. When the application starts, Revel will parse all message files with a valid extension in the messages/
directory and merge them according to their
language. This means that you are free to organize the message files however you want.
- Refer to organization for the directory layout
For example, you may want to take a traditional approach and define one single message file per language:
messages/
messages.en
messages.fr
...
Another approach would be to create multiple files for the same language and organize them based on the kind of messages they contain:
messages/
labels.en
warnings.en
labels.fr
warnings.fr
...
Message keys and values
A message file is for all intents and purposes a goconfig file. This means that messages should be defined according to the tried and tested key-value format:
For example:
Sections
A goconfig file is separated into sections. The default section always exists and contains any messages that are not defined in a specific section. For example:
The key=value
message is implicitly put in the default section as it was not defined under another specific section.
For message files all messages should be defined in the default section unless they are specific to a certain region (see Regions for more information).
Regions
Region-specific messages should be defined in sections with the same name. For example, suppose that we want to greet all English speaking users with "Hello"
, all British
users with "Hey"
and all American users with "Howdy"
. In order to accomplish this, we could define the following message file greeting.en
:
For users who have defined English (en
) as their preferred language, Revel would resolve greeting
to Hello
. Only in specific cases where the user’s locale has been
explicitly defined as en-GB
or en-US
would the greeting
message be resolved using the specific sections.
Referencing and arguments
Referencing
Messages in message files can reference other messages. This allows users to compose a single message from one or more other messages. The syntax for referencing other messages
is %(key)s
. For example:
Notes:
- Referencing is a goconfig feature.
- Because message files are merged, it's perfectly possible to reference messages in other files provided they are defined for the same language.
Arguments
Messages support one or more arguments. Arguments in messages are resolved using the same rules as the go fmt
package. For example:
Arguments are resolved in the same order as they are given, see Resolving messages.
Resolving the client locale
In order to figure out which locale the user prefers Revel will look for a usable locale in the following places:
-
Language Parameter value
- If in
app.conf
the value fori18n.locale.parameter
is set, this will be the first method to resolve the client language preference. e.g.i18n.locale.parameter=lang
. - If this parameter has a value, its value is assumed to be the current locale.
- All other resolution methods will be skipped when a language parameter value has been found.
- If in
-
Language cookie
- For every request, Revel will look for a cookie with the name defined in the application configuration
i18n.cookie
. - If such a cookie is found, its value is assumed to be the current locale.
- All other resolution methods will be skipped when a cookie has been found.
- For every request, Revel will look for a cookie with the name defined in the application configuration
-
Accept-Language
HTTP header- Revel will automatically parse the
Accept-Language
HTTP header for each incoming request. - Each of the locales in the
Accept-Language
header value is evaluated and stored in order of qualification according to the HTTP specification - in the currentRequest
instance. - This information is used later by the various message resolving functions to determine the current locale.
- For more information see Parsed Accept-Language HTTP header.
- Revel will automatically parse the
-
Default language
- When all of the look-up methods above have returned no usable client locale, Revel will use the
i18n.default_language
as defined in theconf/app.conf
file.
- When all of the look-up methods above have returned no usable client locale, Revel will use the
Note: When the requested message could not be resolved at all, a specially formatted string containing the original message is returned.
Accept-Language
header is always parsed and stored in the current Request
, even when a language cookie has been found. In such a case, the values from the header are simply never used by the message resolution functions, but they're still available to the application in case it needs them.Retrieving the current locale
The application code can access the current locale from within a Request
using the Request.Locale
property. For example:
From a template, the current locale can be retrieved from the currentLocale
property of viewArgs
. For example:
Parsed Accept-Language HTTP header
In case the application needs access to the Accept-Language
HTTP header for the current request it can retrieve it from the Request
instance of the Controller
. The AcceptLanguages
field
- which is a slice of
AcceptLanguage
instances - contains all parsed values from the respective header, sorted per qualification with the most qualified values first in the slice. For example:
For more information see the HTTP specification.
Resolving messages
Messages can be resolved from either a controller or a view template.
Controller
Each controller has a Message(message string, args ...interface{})
function that can be used to resolve messages using the current locale. For example:
Template
To resolve messages using the current locale from templates there is a template function msg
that you can use. For example:
Notes:
- The signature of the
msg
function ismsg . "message name" "argument" "argument"
. If there are no arguments, simply do not include any. - The I18nFilter filter must be enabled (default) or the
currentLocale
RenderArg set for message substitution to work.
Locale by URL
Adds ability to specify a parameter to be used to set the locale.
In revel app.conf set the i18n.locale.parameter
to the parameter name.
i18n.locale.parameter=locale
In routes specify the route path with the locale
GET /hotels/:locale Hotels.Index