Tipps und Tricks für AngularJS, Teil 1: Internationalisierung

Werkzeuge  –  1 Kommentare

Hat man viel Zeit in die Entwicklung einer Anwendung gesteckt, will man sie in der Regel so vielen Nutzern wie möglich zugänglich machen. Für weltweilten Erfolg sind einige landesspezifische Anpassungen nötig, bei denen das Modul angular-translate helfen kann.

Während der Entwicklung bezeichnet Internationalisierung Maßnahmen, um Anwendungen für unterschiedliche Kulturen, Sprachen und Regionen einfach anpassen zu können. Mit AngularJS 1.4 soll sich zwar einiges ändern, in der hier betrachteten Version 1.3 gibt es diesbezüglich allerdings nur wenig Unterstützung. Darunter fallen die bekannten Filter date und number, die ein Datum beziehungsweise eine Zahl entsprechend der Gepflogenheiten einer bestimmten Region oder einer bestimmten Sprache formatieren.

Als Ergänzung kann beispielsweise das freie Modul angular-translate dienen. Es bietet eine Vielzahl an Möglichkeiten bei der Umsetzung von Übersetzungen. Dazu zählen unterschiedliche Ladestrategien für Übersetzungen von Titeln, Texten oder Beschriftungsfeldern, deren Einbinden in die Anwendung unter Berücksichtigung von Platzhaltern sowie ein Sprachwechsel zur Laufzeit.

Um angular-translate nutzen zu können, ist zunächst die im Lieferumfang enthaltene Skript-Datei angular-translate.js in das Projekt einzubinden. Zusätzlich referenziert man das von letzterer bereitgestellte Modul pascalprecht.translate.

Installation via Bower

Entwickler können die im Beitrag genutzten Teile von angular-translate komfortabel mit dem Paketmanager Bower installieren. Dazu sind die nachfolgenden Anweisungen auf der Kommandozeile einzugeben:

bower install angular-translate
bower install angular-translate-loader-url
bower install angular-translate-loader-static-files
bower install angular-translate-loader-partial

Zum Bereitstellen einer Konfiguration kommt, wie unter AngularJS üblich, eine an die Funktion config übergebene Konfigurationsfunktion zum Einsatz. Sie lässt sich dem $translateProvider injizieren, wie folgendes Beispiel veranschaulicht:

var app = angular.module("demo",
["pascalprecht.translate"]);

app.config(function($translateProvider) {

$translateProvider.translations('de', {
GRUSS: 'Hallo {{name}}!',
STATUS: {
INFO: "Heute ist ein schöner Tag!"
}
});

$translateProvider.translations('en', {
GRUSS: 'Hello {{name}}!',
STATUS: {
INFO: "It's a nice day today!"
}
});
$translateProvider.preferredLanguage("de");
});

Es nutzt die von $translateProvider angebotene Funktion translations, um zunächst deutsche Texte festzulegen. Der erste Parameter repräsentiert dabei das Kürzel der Sprache; der zweite ein Objekt mit Texten, das angular-translate als Übersetzungstabelle (translation table) bezeichnet. Letztere bildet sogenannte Übersetzungs-IDs (translation-ids) auf Texte der jeweiligen Sprache ab. Diese können Platzhalter aufweisen, die eine Interpolator genannte austauschbare Komponente zur Laufzeit durch konkrete Werte ersetzt. Der standardmäßig von angular-translate genutzte Interpolator verwendet dazu jene Möglichkeiten, die AngularJS auch im Zuge der Datenbindung nutzt. Deswegen sind die Platzhalter in zwei geschweifte Klammern einzuschließen. Das eben betrachtete Beispiel definiert so name.

Anhand der Eigenschaft INFO ist zu sehen, dass Entwickler Einträge schachteln können, um sie nach Themenbereichen zu gruppieren. Solche Hierarchien drückt angular-translate flach und nutzt Schlüssel, die sich aus denen der Hierachie zusammensetzen. Für den betrachteten Eintrag vergibt angular-translate beispielsweise den Schlüssel STATUS.INFO.

Der zweite Aufruf von translations hinterlegt für dieselben IDs englische Gegenstücke. Um Deutsch als bevorzugte Sprache festzulegen, ruft der oben gezeigte Programmcode die Funktion preferredLanguage auf und übergibt dabei das zuvor festgelegte Kürzel de.

Der folgende Codeausschnitt für einen Controller bietet die Möglichkeit, zwischen den konfigurierten Sprachen zu wechseln:

app.controller("DemoCtrl", function($scope, $translate) { 
$scope.model = {};
$scope.model.setCulture = function() {
$translate.use($scope.model.culture);
}
$scope.model.culture = $translate.preferredLanguage();
});

Dazu bekommt er den Service $translate injiziert. Die im Scope eingerichtete Funktion setCulture nutzt dessen use, um zur in $scope.model.culture hinterlegten Sprache zu wechseln. Diese Eigenschaft bekommt die eingangs konfigurierte bevorzugte Sprache zugewiesen.

Das Markup im nächsten Quelltextauszug verwendet den gezeigten Controller:

<div ng-app="demo" ng-controller="DemoCtrl">
<h1>{{ 'GRUSS' | translate:{name:'Max'} }}</h1>
<p>
<span translate="GRUSS" translate-values="{name:'Max'}"
translate-default="Moin!"></span>
{{ 'STATUS.INFO' | translate }}
</p>
<div>
<form>
<input ng-model="model.culture"><input type="button"
ng-click="model.setCulture()" value="Ok">
</form>
</div>
</div>

Es verwendet den Filter translate, um innerhalb des h1-Elements den Text, der hinter der ID GRUSS steht, für die aktuell festgelegte Sprache auszugeben. Der erste Parameter des Filters ist ein Objekt, das Werte für die definierten Platzhalter enthält. Kann der Filter für die angegebene ID keinen Eintrag finden, schreibt er stattdessen die ID in die Seite. Im darauf folgenden p-Element nutzt das Markup die Direktive translate für denselben Zweck.

Das Attribut translate erhält dabei die zu nutzende ID und translate-values, ein Objekt mit Werten für die festgelegten Platzhalter. Ist die Direktive nicht in der Lage, einen Eintrag zu finden, nimmt sie mit dem im Attribut translate-default hinterlegten Wert vorlieb. Haben Entwickler das Attribut nicht eingerichtet, verhält sich translate, wie der gleichnamige Filter und nutzt die ID statt der Übersetzung.

Zusätzlich veranschaulicht das Beispiel die Nutzung hierarchisch organisierter Übersetzungstabelleneinträge, indem es die ID STATUS.INFO nutzt. Das Formular am Ende des Markups gibt Entwicklern die Möglichkeit, zur Laufzeit die Sprache zu wechseln. Dazu bindet es die Eigenschaft model.culture, mit der der Controller die aktuelle Sprache repräsentiert, an ein Eingabefeld und die Funktion setCulture, die die erfasste Sprache als aktuelle Sprache festlegt, an eine Schaltfläche.