javascript 角度国际化翻译
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript 角度国际化翻译相关的知识,希望对你有一定的参考价值。
// ----------------------------------------------------------
// TUTORIAL (ANGULAR-TRANSLATE)
//
// https://malyw.github.io/angular-translate-yeoman/dist/
// *Some of the code examples in this article are shown in a reduced manner. CHECK THE REPO FOR COMPLETE CODE
// Repo: https://scotch.io/tutorials/internationalization-of-angularjs-applications
// Demo: https://hospodarets.com/angular-translate-yeoman/dist/#/
// Let's provide asynchronous translate (without page reload) to our AngularJS application. We'll use:
//
//1) Download libraries and include in project
//
// ANGULAR-TRANSLATE STUFF (handles language translation stuff)
//adds angular-translate library
npm install --save angular-translate
//util for asynchronous loading translations files
npm install --save angular-translate-loader-static-files
//util to save selected language preferences to localStorage
npm install --save angular-translate-storage-local
//util to track missed IDs in translation files
npm install --save angular-translate-handler-log
// ANGULAR-DYNAMIC-LOCALE STUFF (changes angular $locale, which means formatting dates, numbers, currencies, etc)
//adds angular-dynamic-locale library
npm install --save angular-dynamic-locale
//list of predefined settings for each locale
npm install --save angular-i18n
//**ALTERNATIVE: angular-translate-storage-local
//Including angular-translate and dynamic loading in AngularJS applications
angular.module('translateApp', [
...
'pascalprecht.translate',// angular-translate
'tmh.dynamicLocale'// angular-dynamic-locale
])
.constant('LOCALES', { //Provide info about locales
'locales': {
'ru_RU': 'Русский', //key values will be used in languages dropdown
'en_US': 'English'
},
'preferredLocale': 'en_US' //preferred locale which are used in your app
})
.config(function ($translateProvider) {
$translateProvider.useMissingTranslationHandlerLog(); //get warnings in the developer console: forgotten IDs in translations
})
.config(function ($translateProvider) { //adding asynchronous loading for the translations
$translateProvider.useStaticFilesLoader({
prefix: 'resources/locale-',// path to translations files
suffix: '.json'// extension of the translation files
});
$translateProvider.preferredLanguage('en_US');// is applied on first load
$translateProvider.useLocalStorage();// saves selected language to localStorage
})
//finally, provide the config with direction of where to load the $locale settings files for angular-dynamic-locale:
.config(function (tmhDynamicLocaleProvider) {
tmhDynamicLocaleProvider.localeLocationPattern('bower_components/angular-i18n/angular-locale_{{locale}}.js');
})
//
//2) Providing Translations Files and applying translations in the templates
//
//Create one file per locale you need, follwowing this syntax:
app/resources/locale-{{locale}}.json
//example
app/resources/locale-en_US.json //for English (United States):
{
"views.main.Splendid!": "Splendid!", //naming conventions: 'views' folder, 'main.html' file
"directives.language-select.Language": "Language" //* will be used in languages dropdown
}
app/resources/locale-ru_RU.json //for Russian (Russia):
{
"views.main.Splendid!": "Отлично!",
"directives.language-select.Language": "Язык"
}
// so you can use like this in the templates
{{"views.main.Splendid!" | translate}}
//
//3) AngularJS service for getting / setting current locale + Language dropdown
//
// we need a service to change language and apply some additional logic (e.g. change AngularJS $locale).
// This will be used for creation and interaction with the languages drop down later.
//LocaleService.js
angular.module('translateApp') .service('LocaleService', function ($translate, LOCALES, $rootScope, tmhDynamicLocale) {
'use strict';
// PREPARING LOCALES INFO
var localesObj = LOCALES.locales;
// locales and locales display names
var _LOCALES = Object.keys(localesObj);
if (!_LOCALES || _LOCALES.length === 0) {
console.error('There are no _LOCALES provided');
}
var _LOCALES_DISPLAY_NAMES = [];
_LOCALES.forEach(function (locale) {
_LOCALES_DISPLAY_NAMES.push(localesObj[locale]);
});
// STORING CURRENT LOCALE
var currentLocale = $translate.proposedLanguage();// because of async loading
// METHODS
var checkLocaleIsValid = function (locale) {
return _LOCALES.indexOf(locale) !== -1;
};
var setLocale = function (locale) {
if (!checkLocaleIsValid(locale)) {
console.error('Locale name "' + locale + '" is invalid');
return;
}
currentLocale = locale;// updating current locale
// asking angular-translate to load and apply proper translations
$translate.use(locale);
};
// EVENTS
// on successful applying translations by angular-translate
$rootScope.$on('$translateChangeSuccess', function (event, data) {
document.documentElement.setAttribute('lang', data.language);// sets "lang" attribute to html
// asking angular-dynamic-locale to load and apply proper AngularJS $locale setting
tmhDynamicLocale.set(data.language.toLowerCase().replace(/_/g, '-'));
});
return {
getLocaleDisplayName: function () {
return localesObj[currentLocale];
},
setLocaleByDisplayName: function (localeDisplayName) {
setLocale(
_LOCALES[
_LOCALES_DISPLAY_NAMES.indexOf(localeDisplayName)// get locale index
]
);
},
getLocalesDisplayNames: function () {
return _LOCALES_DISPLAY_NAMES;
}
};
});
// Language Dropdown
//This select element has to be shown only when there are more than 1 languages provided.
//** NOSOTROS HACER UN COMPONENT **
//LanguageSelectDirective.js
angular.module('translateApp') .directive('ngTranslateLanguageSelect', function (LocaleService) { 'use strict';
return {
restrict: 'A',
replace: true,
template: ''+
'<div class="language-select" ng-if="visible">'+
'<label>'+
'{{"directives.language-select.Language" | translate}}:'+
'<select ng-model="currentLocaleDisplayName"'+
'ng-options="localesDisplayName for localesDisplayName in localesDisplayNames"'+
'ng-change="changeLanguage(currentLocaleDisplayName)">'+
'</select>'+
'</label>'+
'</div>'+
'',
controller: function ($scope) {
$scope.currentLocaleDisplayName = LocaleService.getLocaleDisplayName();
$scope.localesDisplayNames = LocaleService.getLocalesDisplayNames();
$scope.visible = $scope.localesDisplayNames &&
$scope.localesDisplayNames.length > 1;
$scope.changeLanguage = function (locale) {
LocaleService.setLocaleByDisplayName(locale);
};
}
};
});
// Including locale service and language select
<div ng-translate-language-select></div>
//
// TIPS and TRICKS
//
// apply translations for templates using translate filter:
{{"views.main.Splendid!" | translate}}
//To apply a changing page title and a meta[name="description"] attribute
//you can use angular ng-bind and ng-attr-content directives (see how it's done in the demo app):
<title ng-bind="pageTitle">i18n for your AngularJS applications</title>
<meta name="description" ng-attr-content="{{pageContent}}" content="How to translate your AngularJS applications without page reload with angular-translate">
//
//and to provide an update to these fields in controller:
$translate(pageTitleTranslationId, pageContentTranslationId)// ON INIT
.then(function (translatedPageTitle, translatedPageContent) {
$rootScope.pageTitle = translatedPageTitle;
$rootScope.pageContent = translatedPageContent;
});
$rootScope.$on('$translateChangeSuccess', function (event, data) {// ON LANGUAGE CHANGED
$rootScope.pageTitle = $translate.instant(pageTitleTranslationId);
$rootScope.pageContent = $translate.instant(pageContentTranslationId);
});
//Images
//You can replace your images when you switch the language providing {{locale}} part to ng-src attribute in your views:
<img ng-src="images/no-filerev/yeoman-{{locale}}.png" />
//And in the controller:
$scope.locale = $translate.use();// ON INIT
$rootScope.$on('$translateChangeSuccess', function (event, data) {// ON LANGUAGE CHANGED
$scope.locale = data.language;
});
//CSS
//apply some specific css depending on current locale
//in our example we provided the lang attribute for the <html/> tag with current locale value **CHECK ESTO**
//so we can do:
[lang="ru_RU"]{
/*some special styles*/
}
// ANGULAR-GETTEXT
$ npm install --save angular-gettext
import gettext from 'angular-gettext';
//Configuring angular-gettext
angular.module('myApp', [gettext])
.run(function (gettextCatalog) { //You can do this anywhere in your application, the use of a run block above is just an example.
gettextCatalog.setCurrentLanguage('nl'); //Set the language
gettextCatalog.debug = true; //Eenable a debugging mode: will prepend [MISSING] to untranslated strings
});
//
//1) Annotate your application using the 'translate' directive
//
// mark the strings that are translatable
<h1 translate>Hello!</h1>
//
//You can also use the translate directive as an element:
<translate>Hello!</translate>
//
//interpolation support is available in translated strings
<div translate>Hello {{name}}!</div>
//
//Plural strings can be annotated using two extra attributes: translate-n and translate-plural:
<div translate translate-n="COUNTEXPR" translate-plural="PLURALSTR">SINGULARSTR</div>
//
//Depending on the value of COUNTEXPR, either the singular string or the plural string will be selected.
//Inside the strings, you can use any variable that is available in the scope.
//A special $count variable is also available, which resolves to the value of the translate-n attribute (accepts any valid Angular.JS expression, even functions).
<div translate translate-n="boatCount" translate-plural="{{$count}} boats">One boat</div>
//
//Sometimes it's not an option to use an attribute (e.g. when you want to annotate an attribute value).
//Here you use filter instead of directive.
<input type="text" placeholder="{{'Username'|translate}}" />
//This filter does not support plural strings.
//*You may want to use custom annotations <https://angular-gettext.rocketeer.be/dev-guide/custom-annotations/> to avoid using the translate filter all the time.
//Contexts can be added via 'translate-context' to strings to be translated.
//The translation for the same string in a different context can be different.
<h1 translate-context="Verb" translate>File</h1>
<h1 translate-context="Noun" translate>File</h1>
//The contexts will appear in the catalog (as msgctxt).
//In the application Poedit, the contexts will appear under "Context" (ver pantallazo)
//Comments can be added to the catalog to help translators with the context of the translatable string.
<div translate-comment="{{name}} expands to the logged in user name" translate>Hello {{name}}!</div>
//
//In the application Poedit, the comment will appear under "Notes for translators" section (ver pantallazo)
// TRANSLATIONS IN THE CONTROLLER
// If you have text that should be translated in your JavaScript code, wrap it with a call to a function named gettext.
// This module provides an injectable function to do so:
angular.module("myApp").controller("helloController", function (gettext) {
var myString = gettext("Hello"); //Hello string will be added to your .pot file
});
// update your Grunt/Webpack task to include the JavaScript files:
grunt.initConfig({
nggettext_extract: {
pot: {
'po/template.pot': ['src/views/*.html', 'src/js/*.js']
},
},
})
//You can inject gettextCatalog to fetch translated strings in JavaScript. Use the getString method for this.
angular.module("myApp").controller("helloController", function (gettextCatalog) {
var translated = gettextCatalog.getString("Hello"); //Any string passed to gettextCatalog.getString() is automatically marked for translation. In other words: no need to annotate these strings with gettext().
});
//This also works for plurals:
angular.module("myApp").controller("helloController", function (gettextCatalog) {
var myString2 = gettextCatalog.getPlural(3, "One Bird", "{{$count}} Birds", {});
});
//*It's not recommended to put translated strings on the scope. Use the 'filter' for translations in views.
//*The JavaScript API is meant for strings that are used in library code.
//You can pass a data object to interpolate the translated strings:
var translated = gettextCatalog.getString("Hello {{name}}", { name: "Ruben" });
//you can insert context comments for poedit using the triple forward slash syntax of gettext:
angular.module("myApp").controller("helloController", function (gettext) {
/// Verb
var myString = gettext("File");
});
//You can set translated strings by injecting the gettextCatalog and using the setStrings method.
angular.module("myApp").run(function (gettextCatalog) {
// Load the strings automatically during initialization.
gettextCatalog.setStrings("nl", { //language code
//dictionary of strings:
// - Keys: Singular English strings (as defined in the source files)
// - Values: Either a single string for signular-only strings or an array of plural forms.
"Hello": "Hallo",
"One boat": ["Een boot", "{{$count}} boats"]
});
});
//* CHECK: CUSTOM ANNOTATIONS: https://angular-gettext.rocketeer.be/dev-guide/custom-annotations/
//
//2) Extracting strings
//
// Once you've annotated your application is time to extract these strings into a translation template: a standard .pot file
// Angular-gettext-tools (grunt) is the official library to extract strings from HTML templates and JavaScript code. Several wrappers exist that integrate it with other tools:
// Third party
// - CLI utility: https://github.com/huston007/angular-gettext-cli
// - Webpack loader (compilation):https://github.com/princed/angular-gettext-loader
// - ***[ESTE ES EL GUAY, REVISAR] Webpack plugin (compilation and extraction):https://github.com/augusto-altman/angular-gettext-plugin
//
//3) Translating strings
//
// There are several translation tools. Here we'll use Poedit: http://www.poedit.net/
// 1) Use the .pot template as the basis for translation. This will generate a new translation catalog (a .po file) or updates an existing .po file.
// 2) Start Poedit and choose 'File > New Catalog from POT File...' Locate your .pot file.
// 3) In "Catalog properties" dialog:
// > Language: example 'fr'
// > Plural Forms: example 'nplurals=2; plural=(n > 1)' *be sure to not to put ';' at the end!
// Check here the correct values for these fields: http://docs.translatehouse.org/projects/localization-guide/en/latest/l10n/pluralforms.html?id=l10n/pluralforms
//4) Save the new fr.po file in a 'po' folder, next to the .pot file (convention for gettext projects). Some gettext translation tools will also generate compiled .mo files (we won't be using them).
//5) Translate the strings and save your catalog.
//*If you make changes to your project later, simply run 'grunt' (or webpack) again to generate a new .pot template.
// Then in poedit open your .po file and ' Catalogue > Update from POT File'
// This will update your translation catalog by adding new strings, removing obsolete ones and flagging slightly changed ones for review.
//
//4) Compiling translations
//
// Converting translated .po files into angular-compatible JavaScript files can be done automatically using the grunt-angular-gettext module (or corresponding webpack https://github.com/augusto-altman/angular-gettext-plugin or CLI tool https://github.com/huston007/angular-gettext-cli)
// the task converts a set of translated .po files into a JavaScript file that can be included in your project.
// Be sure to add this file (in this case src/js/translations.js) to your project.
//*Optionally, you can specify a module parameter, which defines the Angular.JS module for which the translations JavaScript is generated:
//If you have a lot of languages (or a lot of strings) the resulting JavaScript file would become too big.
//There's another option: lazy-load the languages, only when you need them.
//Instead of compiling to JavaScript (the default), configure your grunt task to output JSON files (ver webpack plugin)
//This will generate a dist/languages/XX.json file for each po/XX.po.
//gettextCatalog() provides a 'loadRemote' method to easily load new languages.
//Whenever you change the application languages, do something like this:
angular.module("myApp").controller("helloController", function ($scope, gettextCatalog) {
$scope.switchLanguage = function (lang) {
gettextCatalog.setCurrentLanguage(lang);
gettextCatalog.loadRemote("/languages/" + lang + ".json");
};
});
//All translations will be updated once the strings have been loaded.
//MORE INFO: https://angular-gettext.rocketeer.be/dev-guide/api/angular-gettext/
以上是关于javascript 角度国际化翻译的主要内容,如果未能解决你的问题,请参考以下文章