Localizza gli URL con ui-router e angular-translate

Sto usando ui-router per il routing e angulartranslate per le traduzioni. Quello che mi piacerebbe ottenere è che la lingua selezionata si leghi all’url in questo modo:

www.mydomain.com/en/ www.mydomain.com/ru/ www.mydomain.com/en/about www.mydomain.com/ru/about 

e risponderà di conseguenza.

Ho cercato di cercare degli esempi, ma non ho trovato nulla. Se qualcuno implementasse una soluzione simile, mi piacerebbe sapere come hai fatto.

Grazie

Io uso qualcosa seguendo queste linee:

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' }); } ]); 

Con questo, è ansible iniettare $stateParams nel controller e ottenere l’accesso alle $stateParams locali:

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; } ]); 

Oppure, se si desidera modificare automaticamente l’intera pagina, utilizzare l’evento $stateChangeStart in un controller dell’applicazione o simile:

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); }); 

Nota che se stai usando angular-translate v1.x dovresti usare $translate.uses invece di $translate.use .

La soluzione è valida solo se desideri avere URL del seguente formato:

domain.com/{locale}/about

quindi:

domain.com/en/about domain.com/mt/about

Recentemente ci è stato richiesto di implementare le traduzioni per l’URL completo, quindi:

domain.com/{locale}/{about}

dove {about} è tradotto nella rispettiva lingua:

domain.com/en/about domain.com/mt/fuqna

Non so se l’approccio sotto è il migliore, tuttavia funziona.

Per i principianti, la prima differenza è che configuriamo gli stati del router da generare dynamicmente utilizzando un servizio che recupera i percorsi da un file JSON. Questo è fatto in modo simile alla risposta di @ ChrisT in: Angular – UI Router – aggiungere gli stati a livello di codice

 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; }]); 

Dovremmo quindi utilizzare il suddetto routingService nel blocco di run dell’applicazione:

 // 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); } }); } ]); 

E infine lo stateService analizza semplicemente il file JSON e crea la gerarchia di routing usando runtimeStates.addState di ChrisT.

Proverò a includere una demo funzionante nel prossimo futuro.

Anche i crediti vanno a @karl-agius.

Ho scritto un post sul blog sulla questione esatta: http://fadeit.dk/post/angular-translate-ui-router-seo

Per le persone che vorrebbero includere l’URL utilizzando ngRoute (sono venuto qui a cercare su google esattamente per quello), l’ho implementato come segue.

(1) Nel mio .htaccess ho preso tutti gli URL senza un sottodominio della lingua e l’ho reindirizzato al default (nel mio caso fr). L’unico vero svantaggio è che devo specificare manualmente ogni lingua.

 # 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) Nel blocco di config del mio progetto angular ho quindi semplicemente analizzato l’URL per ottenere la lingua corrente.

 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) Per ottenere la lingua nei miei file HTML, l’ho aggiunta anche a $rootScope .

 run.$inject = ['$window', '$rootScope']; function run($window, $rootScope ) { $rootScope.language = $window.location.pathname.replace(/\//g, ''); }