J'utilise ui-router pour le routage et angular-translate pour les traductions. Ce que je voudrais réaliser, c'est que la langue sélectionnée soit liée à l'URL comme ceci:
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.
J'ai essayé de chercher des exemples, mais je n'ai rien trouvé. Si quelqu'un implémentait une solution similaire, j'aimerais savoir comment vous l'avez fait.
Merci
J'utilise quelque chose dans ce sens:
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 cela, vous pouvez injecter $stateParams
dans votre contrôleur et accédez-y aux paramètres régionaux:
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 souhaitez affecter automatiquement la page entière, utilisez le $stateChangeStart
événement 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 angular-translate v1.x, vous devez utiliser $translate.uses
au lieu de $translate.use
.
La solution n'est valide que si vous souhaitez avoir des URL du format ci-dessous:
domain.com/{locale}/about
par conséquent:
domain.com/en/about domain.com/mt/about
Récemment, nous avons dû implémenter des traductions pour l'URL complète, donc:
domain.com/{locale}/{about}
où {about}
est traduit dans la langue respective:
domain.com/en/about domain.com/mt/fuqna
Je ne sais pas si l'approche ci-dessous est la meilleure, mais elle fonctionne.
Pour commencer, la première différence est que nous configurons des états ui-router à générer dynamiquement à l'aide d'un service qui récupère les routes à partir d'un fichier JSON. Cela se fait de la même manière que la réponse de @ ChrisT dans: Angular - UI Router - programmically add states
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 routingService
ci-dessus dans le bloc run
de l'application:
// 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);
}
});
}
]);
Enfin, le stateService
analyse simplement le fichier JSON et crée la hiérarchie de routage à l'aide de runtimeStates.addState de ChrisT.
J'essaierai d'inclure une démonstration de travail dans un avenir proche.
Les crédits vont également à @ karl-agius.
J'ai écrit un article de blog sur la question exacte: http://fadeit.dk/post/angular-translate-ui-router-seo
Pour les personnes qui souhaitent inclure l'URL à l'aide de ngRoute (je suis venu ici pour rechercher exactement cela), je l'ai implémenté comme suit.
(1) Dans mon .htaccess
J'ai récupéré toutes les URL sans sous-domaine de langue et l'ai redirigé vers la valeur par défaut (fr dans mon cas). Le seul véritable 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)$ $1/ [R=301,L]
# now all urls have nl/ fr/ -> parse them
RewriteRule ^(nl|fr)/(.*)$ $2?lang=$1&%{query_STRING} [L]
(2) Dans mon bloc Angular du projet config
, j'ai simplement analysé l'URL pour obtenir la langue actuelle.
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 également ajoutée au $rootScope
.
run.$inject = ['$window', '$rootScope'];
function run($window, $rootScope ) {
$rootScope.language = $window.location.pathname.replace(/\//g, '');
}