Localisez les URL avec ui-router et angular-translate
j'utilise ui-router pour le routage et angular-translate pour les traductions. Ce que je voudrais réaliser, c'est que la langue choisie soit liée à l'url comme suit:
www.mydomain.com/en/
www.mydomain.com/ru/
www.mydomain.com/en/about
www.mydomain.com/ru/about
et il répondra en conséquence.
a essayé de chercher des exemples, mais n'a rien trouvé. Si quelqu'un implémentait une solution similaire, j'aimerais savoir comment vous l'avez fait.
Merci
4 réponses
j'utilise quelque chose le long de ces lignes:
CoffeeScript
angular.module('app')
.config([
'$stateProvider'
($stateProvider) ->
$stateProvider.state 'app',
abstract: true
url: '/{locale}'
$stateProvider.state 'app.root',
url: ''
$stateProvider.state 'app.root.about',
url: '/about'
])
JavaScript
angular.module('app').config([
'$stateProvider', function($stateProvider) {
$stateProvider.state('app', {
abstract: true,
url: '/{locale}'
});
$stateProvider.state('app.root', {
url: ''
});
return $stateProvider.state('app.root.about', {
url: '/about'
});
}
]);
avec ceci, vous pouvez injecter $stateParams
dans votre contrôleur et y accéder:
CoffeeScript
angular.module('app')
.controller('appCtrl', [
'$scope', '$stateParams'
($scope, $stateParams) ->
$scope.locale = $stateParams.locale
])
JavaScript
angular.module('app').controller('appCtrl', [
'$scope', '$stateParams', function($scope, $stateParams) {
return $scope.locale = $stateParams.locale;
}
]);
ou, si vous voulez affecter la page entière automatiquement, utilisez l'événement $stateChangeStart
dans un contrôleur d'application ou similaire:
CoffeeScript
$scope.$on '$stateChangeStart', (event, toState, toParams, fromState, fromParams) ->
$translate.use(toParams.locale)
JavaScript
$scope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
$translate.use(toParams.locale);
});
Notez que si vous utilisez angulaires-traduction v1.x vous devez utiliser $translate.uses
au lieu de $translate.use
.
la solution n'est valable que si vous voulez avoir des URLs au format ci-dessous:
domain.com/{locale}/about
d'où:
domain.com/en/about
domain.com/mt/about
récemment, nous avons dû mettre en œuvre des traductions pour L'URL complète, donc:
domain.com/{locale}/{about}
où {about}
est traduit dans la langue correspondante:
domain.com/en/about
domain.com/mt/fuqna
je ne sais pas si l'approche est la meilleure, mais elle fonctionne.
pour commencer, la première différence est que nous configurons des états de routeur ui pour être générés dynamiquement en utilisant un service qui récupère les routes à partir d'un fichier JSON. Ceci est fait de la même manière que la réponse de @ChrisT dans: Routeur angulaire-UI - ajouter programmatiquement les États
module.service("routingService", ["$http", function($http) {
self.get = function(options) {
return self.getByLocale({
market: options.urlMarketCode
});
};
self.getByLocale = function(options) {
var market = options.market;
// loads the different .json files based on the different market values passed, ex: routes-en.json
var configurationKey = "routes-" + market;
return $http({
method: "GET",
url: configurationKey + ".json",
headers: {
"Content-Type": "application/json"
}
}).then(function(response) {
if (response.data) {
return response.data;
}
return undefined;
}).catch(function(e) {
console.log(e);
});
};
return self;
}]);
nous consommerions alors le ci-dessus routingService
dans le bloc run
de la demande:
// run the module and register the state change handler
angular.module("sportsbook-app").run(["$state", "$rootScope", "routingService", "stateService",
function ($state, $rootScope, routingService, stateService) {
// retrieve the routing heirarchy from file
routingService.get({
urlMarketCode: $rootScope.language
}).then(function (response) {
if (response) {
// add the routes to the $stateProvider
stateService.generate(response);
}
});
}
]);
et finalement le stateService
analyse simplement le fichier JSON et crée la hiérarchie de routage en utilisant les États d'exécution de ChrisT.addState.
je vais essayer d'inclure une démo de travail dans un futur proche.
Les crédits devont aussi à @karl-agius.
j'ai écrit un billet de blog sur le sujet: http://fadeit.dk/post/angular-translate-ui-router-seo
pour les personnes qui voudraient inclure L'URL en utilisant ngRoute (je suis venu ici googler pour exactement cela), je l'ai mis en œuvre comme suit.
(1) dans mon .htaccess
j'ai saisi toutes les URLs sans sous-domaine de langue et je l'ai redirigé vers la valeur par défaut (fr Dans mon cas). Le seul vrai inconvénient est que je dois spécifier chaque langue manuellement.
# https://stackoverflow.com/questions/19570572/htaccess-multi-language-site-with-sub-directories-and-default-301/19902914#19902914
# Add language to URL - redirect to default if missing
RewriteBase /
# empty url -> redirect to nl/
RewriteCond %{QUERY_STRING} !lang=(nl|fr)
RewriteRule ^$ fr/ [R=301,L]
# url is ONLY '/nl' or '/fr' -> redirect to /nl/ or /fr/ (adding slash)
RewriteRule ^(nl|fr)$ / [R=301,L]
# now all urls have nl/ fr/ -> parse them
RewriteRule ^(nl|fr)/(.*)$ ?lang=&%{query_STRING} [L]
(2) dans le bloc config
de mon projet angulaire, j'ai simplement analysé L'URL pour obtenir langage courant.
config.$inject = ['$translateProvider', '$windowProvider'];
function config($translateProvider, $windowProvider) {
var $window,
language;
$window = $windowProvider.$get();
language = $window.location.pathname.replace(/\//g, '');
//////
$translateProvider
.useStaticFilesLoader({
prefix: 'translations/',
suffix: '.json'
})
.useSanitizeValueStrategy('sanitizeParameters')
.preferredLanguage( language )
}
(3) afin d'obtenir la langue dans Mes fichiers HTML, je l'ai aussi ajouté au $rootScope
.
run.$inject = ['$window', '$rootScope'];
function run($window, $rootScope ) {
$rootScope.language = $window.location.pathname.replace(/\//g, '');
}