adonis install @adonisjs/antl
You are viewing the legacy version of AdonisJS. Visit https://adonisjs.com for newer docs. This version will receive security patches until the end of 2021.
AdonisJs has first class support for internationalization built on top of formatjs.io standards. You can easily translate numbers, dates, and messages for multiple languages.
Since the provider to add Intl support is not installed by default. We need to pull it from npm.
adonis install @adonisjs/antl
Moreover, next, make sure to register the provider inside start/app.js
file.
const providers = [
'@adonisjs/antl/providers/AntlProvider'
]
The configuration for locales is saved inside config/app.js
file, with following options.
Option | Value | Description |
---|---|---|
locale |
ISO 639 |
The locale to be used as the default locale for the application. It must be one of the available locales from ISO 639 codes |
loader |
database or file |
The loader to be used for loading messages for different languages. |
The locales for the file
loader are stored inside resources/locales
directory. Each language gets its directory with a flat list of files inside it.
└── resources
└── locales
├── en
├── fr
└── it
You can also create a directory named fallback
to store messages which are used when the message for current language is missing.
When making use of database
loader, all the locales are fetched from the database table called locales
.
The adonis install
command does create the migration for the table. However, you can always reference the latest schema file from github
id | locale | group | item | text |
---|---|---|---|---|
1 |
en |
cart |
total |
Cart total is {total, number, usd} |
2 |
fr |
cart |
total |
Le panier est total {total, number, usd} |
It is mandatory to define a group for each locale item.
|
AdonisJs uses ICU Message syntax ( industry standard ) to format messages.
The following topics define the usage of ICU message syntax.
You can pass dynamic arguments to the message, which replaces the placeholder values under { }
curly braces.
{
"greeting": "Hello {name}"
}
Antl.formatMessage('messages.greeting', { name: 'virk' })
The values passed to the message can also be formatted for a certain type. For example: When passing a number to the message, we can format it as a currency
.
{
"total": "Cart total is {total, number, usd}"
}
Here total
is the value to the passed in the message.
The number
is the type of the value.
Finally, usd
is the format for the total
value.
The ICU message syntax doesn’t understand the formats directly, so we need to pass them manually when formatting the message.
You also have to register the formats before passing them to the message. Learn more about registering formats. |
const Antl = use('Antl')
const Formats = use('Antl/Formats')
Antl.formatMessage(
'cart.total',
{ total: 20 },
[Formats.pass('usd', 'number')]
)
All we are doing here is calling formatMessage
with 3 arguments.
The first is the reference to the message to be formatted.
Next the data
to be passed
Finally, we pass an Array of formats.
The select
format makes it easy to choose an output by matching value to one of many choices.
Try and edit the below message in your browser |
{gender, select,
male {He}
female {She}
other {They}
} will respond shortly
Also, you define the options on how to pluralize the keywords inside a locale message.
Try and edit the below message in your browser |
{count, plural,
=0 {No candy left}
one {Got # candy left}
other {Got # candies left}
}
Below is the list of methods you can use to format messages or raw values.
The formatMessage
method, takes the key
to be formatted with an object of data and formats to be used.
const Antl = use('Antl')
Antl.formatMessage('response.eta', { gender: 'male' })
Also, you can pass an array of formats.
const Antl = use('Antl')
const Formats = use('Antl/Formats')
Antl.formatMessage(
'cart.total',
{ total: 20 },
[
Formats.pass('usd', 'number')
]
)
Format value as a number. It also takes an object of options defined here.
Antl.formatNumber(10)
// as currency
Antl.formatNumber(10, {
style: 'currency',
currency: 'usd'
})
// as percentage
Antl.formatNumber(10, {
style: 'percent'
})
Format value with style
set to currency.
Antl.formatAmount(100, 'usd')
Format value as date. It also takes an object of options defined here.
Antl.formatDate(new Date())
// pull weekday for the date
Antl.formatDate(new Date(), {
weekday: 'long'
})
// pull day only
Antl.formatDate(new Date(), {
day: '2-digit'
})
Format a date relative to the current date/time. Here is the list of available options
Antl.formatRelative(new Date())
// always in numeric style
Antl.formatRelative(new Date(), {
style: 'numeric'
})
The formatMessage method only takes an array of pre-registered formats. Here is how you can register your formats for a given type.
const Formats = use('Antl/Formats')
Formats.add('usd', {
style: 'currency',
currency: 'usd'
})
Use it as follows
Antl.formatMessage(
'cart.total'
{ total: 20 },
[
Formats.pass('usd', 'number')
]
)
The Formats.pass
takes 2 arguments.
The first argument is the format to be used
2nd is the type
to which format should be passed.
Also, you can pass multiple formats to a given type. For example:
{
"total": "Usd total { total, number, usd } or in GBP { gbpTotal, number, gbp }"
}
Next, register the usd
and gbp
formats.
Formats.add('usd', {
style: 'currency',
currency: 'usd'
})
Formats.add('gbp', {
style: 'currency',
currency: 'gbp'
})
Finally, you can format the message as follows:
Antl.formatMessage(
'cart.total',
{ total: 20, gbpTotal: 13 },
[
Formats.pass('usd', 'number'),
Formats.pass('gbp', 'number')
]
)
Output
Usd total $20.00 or in GBP £13.00
Antl makes it simple to format locale at runtime when formatting values.
Antl
.forLocale('fr')
.formatMessage('response.eta')
You can also switch between available loaders at runtime by calling loader
method.
Always make sure to call bootLoader before making use of it. Also bootLoader needs to be called only once.
|
const Antl = use('Antl')
// asynchronous
await Antl.bootLoader()
// get antl instance for a booted loader
const AntlDb = Antl.loader('database')
// all methods are available
AntlDb.formatMessage()
The antl provider binds the locale
property to the Http context object.
Route.get('/', ({ locale }) => {
return `User language is ${locale}`
})
The locale property is resolved as follows.
It looks for Accept-Language
HTTP header or lang
query parameter to detect the user language.
Next, matches the user language with the list of available locales configured by your application.
The configured locales are determined by messages saved inside database or file system for given languages.
If user language is not supported by your application, then it will fallback to the default locale defined inside config/app.js
file.
Since we can access the user locale
based upon some standard conventions, you can format messages in one of the following ways.
Import the Antl
provider globally and manually call the forLocale
method when formatting the values.
const Antl = use('Antl')
Route.get('/', ({ locale }) => {
return Antl
.forLocale(locale)
.formatNumber(20, { style: 'currency', currency: 'usd' })
})
However, you can also make use of the antl
object, which is passed to all route handlers like request and response.
Route.get('/', ({ antl }) => {
return antl
.formatNumber(20, { style: 'currency', currency: 'usd' })
})
For example, you can switch locale for renderer view as:
Route.get('/', ({ antl, view }) => {
antl.switchLocale('fr')
return view.render('some-view')
}
Also the Context instance is shared with all the views. So you can access all the available methods inside your view templates.
There is no way to switch loader inside templates. |
{{ antl.formatNumber(20, currency = 'usd', style = 'currency') }}
Alternatively, you can make use of the @mustache
tag to write in multiple lines.
@mustache(antl.formatNumber(
20,
{ currency: 'usd', style: 'currency }
))