2014-06-18 15 views
25

Sto usando ui-router per il routing e angular-translate per le traduzioni. Quello che vorrei raggiungere è avere la legano lingua selezionata per l'url in questo modo:Localizza gli URL con ui-router e angular-translate

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

risposta

29

io uso qualcosa in questo senso:

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, si può INIEZ t $stateParams nel controller e ottenere l'accesso al locale c'è:

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 vuole influenzare l'intera pagina automaticamente, l'uso 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); 
}); 

Si noti che se si sta utilizzando angolare-translate v1.x si dovrebbe usare $translate.uses invece di $translate.use.

+0

Solo una piccola modifica: $ translate.use invece di usi – Leon

+1

Ah, sì - questo sembra essere cambiato tra v1.x V2.x e sto usando v1.x in questo momento - I Prenderò un appunto nella risposta, grazie. – mjtko

+0

Desidero che l'URL abbia un codice lingua quando l'utente naviga alla pagina principale della pagina web da 'dominio.com' ->' dominio.it/it/' Per fare ciò ho bisogno di rilevare prima il linguaggio utente e poi aggiungere i parametri' {locale} 'all'URL. C'è una buona soluzione per questo? – user2814599

2

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

+1

Grazie per il link al tuo post @zozoer. puoi controllare l'app che ho creato: www.azorly.com – Leon

+0

Post molto bello. Questa è la soluzione che stavo cercando – Starfs

+1

Si prega di citare la parte pertinente del post nella tua risposta, vedi http://stackoverflow.com/help/how-to-answer – ValarDohaeris

4

La soluzione è valida solo se si vuole avere URL del formato di seguito:

domain.com/{locale}/about

quindi:

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

Recentemente abbiamo richiesto d implementare traduzioni per l'URL completo, quindi:

domain.com/{locale}/{about}

dove {about} è tradotto nelle rispettive lingue:

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

non so se l'approccio seguito è il migliore uno, tuttavia funziona.

Per i principianti, la prima differenza è che configuriamo gli stati del router da generare dinamicamente utilizzando un servizio che recupera i percorsi da un file JSON. Questo viene fatto in modo simile a @ risposta di Cristo in: Angular - UI Router - programmatically 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; 
}]); 

Vorremmo quindi consumare quanto sopra routingService nel run blocco 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 il stateService analizza semplicemente il file JSON e crea la gerarchia di routing utilizzando runtimeStates.addState di ChrisT.

Proverò a includere una demo funzionante nel prossimo futuro.

Anche i crediti vanno a @ karl-agius.

+0

HI, mi interessa questa soluzione. Potresti per favore indicare un collegamento o un articolo che descrivono questa soluzione in dettaglio? Grazie in anticipo. –

+0

@Seto Ho provato a includere un plunker che simula questo scenario, ma ho dovuto ridimensionarlo leggermente. ** Nota che non sono sicuro di raccomandare questo approccio. ** Se si desidera includere anche la modifica della lingua senza aggiornamento, sarà probabilmente necessario ascoltare gli eventi '$ stateChangeStart' e aggiornare gli stati da lì. ** ** Codice: [Plunker] (http://plnkr.co/edit/r51UEZ) ** URL Demo **: [http://run.plnkr.co/Fxo80MbXmuLfdG5c/#/ it] (http://run.plnkr.co/Fxo80MbXmuLfdG5c/#/en) [http://run.plnkr.co/Fxo80MbXmuLfdG5c/#/sv](http://run.plnkr.co/Fxo80MbXmuLfdG5c/ #/it) –

1

Per le persone che desiderano 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 catturato tutti gli URL senza un sottodominio di lingua e reindirizzato al valore predefinito (fr nel mio caso). 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) In config blocco del mio progetto angolare ho poi 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) Al fine di ottenere la lingua nei miei file HTML ho anche aggiunto alla $rootScope.

run.$inject = ['$window', '$rootScope']; 

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