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

26
demandé sur Leon 2014-06-18 13:17:13

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 .

30
répondu mjtko 2014-06-20 08:55:59

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}

{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 de

vont aussi à @karl-agius.

4
répondu Kevin Farrugia 2017-05-23 10:30:56

j'ai écrit un billet de blog sur le sujet: http://fadeit.dk/post/angular-translate-ui-router-seo

2
répondu ozooner 2015-03-31 19:40:35

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, '');
}
1
répondu ChezFre 2016-08-15 06:00:36