Internationalisation (i18n) and Localisation (l10n) for Ionic Apps
In a previous post, I wrote about how Vardyger's Admin UI uses the Angular UI router for handling routes, defining states and sharing data between views. In this post, we'll update the Admin UI in order to add support for internationalisation (i18n) and localisation (l10n).
Note: I've updated Vardyger's project structure to include a directory for locales
:
├── /app
└── /bower_components
└── /ionic
...
└── /scripts
└── /controllers
├── editor-controller.js
├── main-controller.js
├── preview-controller.js
├── side-menu-controller.js
└── /directives
└── /locales
└── /services
├── posts-service.js
├── app.js
└── /styles
├── main.scss
└── /templates
├── editor-template.html
├── main-template.html
├── preview-template.html
├── side-menu-template.html
├── index.html
...
Install angular-translate
angular-translate is an AngularJS module that makes it easy to add support for internationalisation, localisation, lazy loading and pluralisation to your Ionic apps.
To install angular-translate
, enter the following command:
bower install --save angular-translate
Note: Bower will add the module as a dependency in the project's bower.json
and install angular-translate
in the app/bower_components
directory (as per the Admin UI's .bowerrc
).
We also want to take advantage of angular-translate
's static file loader, so we need to install it too:
bower install --save angular-translate-loader-static-files
Update index.html
Now, we need to update index.html
so that it includes the angular-translate
and the angular-translate-loader-static-files
scripts:
...
<!-- bower:js -->
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-animate/angular-animate.js"></script>
<script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
<script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
<script src="bower_components/ionic/release/js/ionic.js"></script>
<script src="bower_components/ionic/release/js/ionic-angular.js"></script>
<script src="bower_components/angular-translate/angular-translate.js"></script>
<script src="bower_components/angular-translate-loader-static-files/angular-translate-loader-static-files.js"></script>
<!-- endbower -->
...
Update app.js
First, we need to inject the angular-translate
module into our app:
...
angular.module('vardyger', [
'ionic', // inject the Ionic framework
'pascalprecht.translate' // inject the angular-translate module
])
.config(function($ionicConfigProvider, $stateProvider,
$urlRouterProvider, $translateProvider) {
$translateProvider
.useStaticFilesLoader({
prefix: 'scripts/locales/',
suffix: '.json'
})
.registerAvailableLanguageKeys(['en', 'de'], {
'en' : 'en', 'en_GB': 'en', 'en_US': 'en',
'de' : 'de', 'de_DE': 'de', 'de_CH': 'de'
})
.preferredLanguage('de')
.fallbackLanguage('de')
.determinePreferredLanguage()
.useSanitizeValueStrategy('escapeParameters');
...
Then, we need to configure the static files loader by providing a file prefix ('scripts/locales/'
) and a file suffix ('.json'
). We also need to register our language keys, set a preferred language and a fallback language, determine the user's preferred language and choose a sanitization strategy.
Note: So far I have only defined translations (see below) for English (en) and German (de) and mapped them to locales in registerAvailableLanguageKeys()
. For example, if determinePreferredLanguage()
returns 'en_US'
or 'en_GB'
then the static files loader will load 'scripts/locales/en.json'
.
Create some translations
Now, we need to create some translations, locales/en.json
:
{
"MAIN_TEMPLATE_TITLE": "Content",
"PREVIEW_TEMPLATE_TITLE": "Preview",
"EDITOR_TEMPLATE_TITLE": "Editor",
"SIDE_MENU_TEMPLATE_CONTENT": "Content",
"SIDE_MENU_TEMPLATE_NEW_POST": "New Post",
"SIDE_MENU_TEMPLATE_SETTINGS": "Settings",
"ALL_POSTS": "ALL POSTS",
"NO_POSTS": "No posts :(",
"EDIT": "EDIT",
"MARKDOWN": "MARKDOWN",
"PREVIEW": "PREVIEW",
"UPDATE_POST": "UPDATE POST"
}
And, locales/de.json
:
{
"MAIN_TEMPLATE_TITLE": "Inhalt",
"PREVIEW_TEMPLATE_TITLE": "Vorschau",
"EDITOR_TEMPLATE_TITLE": "Editor",
"SIDE_MENU_TEMPLATE_CONTENT": "Inhalt",
"SIDE_MENU_TEMPLATE_NEW_POST": "neuer Beitrag",
"SIDE_MENU_TEMPLATE_SETTINGS": "Einstellungen",
"ALL_POSTS": "Alle Beiträge",
"NO_POSTS": "keine Einträge :(",
"EDIT": "BEARBEITEN",
"MARKDOWN": "MARKDOWN",
"PREVIEW": "VORSCHAU",
"UPDATE_POST": "UPDATE BEITRAG"
}
Update the view templates
We also need to update the project's view templates, for example templates/main-template.html
:
...
<div class="bar bar-subheader bar-stable">
<div class="title title-left padding-left">
<small translate="ALL_POSTS">
</small>
</div>
...
</div>
...
Note: Where possible you should prefer the translateDirective (e.g., translate="ALL_POSTS") to the translateFilter (e.g., 'ALL_POSTS' | translate).
Switch translations
It is also very easy to switch languages, for example templates/side-menu-template.html
:
...
<ion-item menu-close class="item-icon-left item-dark"
ng-click="switchLanguage('de_CH')">
<icon ios="ion-ios-gear" android="ion-settings" default="ion-settings">
</icon>
{{ 'SIDE_MENU_TEMPLATE_SETTINGS' | translate }}
</ion-item>
....
The SideMenuController
(scripts/controllers/side-menu-controller.js):
...
$scope.switchLanguage = function(key) {
$translate.use(key);
};
...
The side menu in English:
The side menu in German:
References:
- GitHub: angular-translate
- GitHub: The Vardyger publishing platform