web-dev-qa-db-ja.com

ui-routerとangular-translateを使用してURLをローカライズする

ルーティングにはui-routerを使用し、翻訳には角度変換を使用しています。私が達成したいのは、選択した言語を次のようにURLにバインドすることです:

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

それに応じて応答します。

例を探してみましたが、何も見つかりませんでした。誰かが同様のソリューションを実装した場合、私はあなたがそれをどのようにしたか聞いてみたいです。

ありがとう

26
Leon

私はこれらの線に沿って何かを使用します:

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

これにより、$stateParamsをコントローラーに挿入し、そこでロケールにアクセスできます。

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

または、ページ全体に自動的に影響を与える場合は、アプリケーションコントローラなどで$stateChangeStartイベントを使用します。

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

Angular-translate v1.xを使用している場合は、$translate.usesではなく$translate.useを使用する必要があることに注意してください。

30
mjtko

ソリューションは、以下の形式のURLが必要な場合にのみ有効です。

domain.com/{locale}/about

したがって:

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

最近、完全なURLの翻訳を実装する必要がありました。

domain.com/{locale}/{about}

どこ {about}はそれぞれの言語に翻訳されています。

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

以下のアプローチが最善のものかどうかはわかりませんが、うまくいきます。

まず、最初の違いは、JSONファイルからルートを取得するサービスを使用して動的に生成されるui-router状態を設定することです。これは、@ ChrisTの回答と同様に行われます。 Angular-UI Router-プログラムで状態を追加

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

次に、アプリケーションのroutingServiceブロックで上記のrunを使用します。

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

そして最後に、stateServiceはJSONファイルを解析し、ChrisTのruntimeStates.addStateを使用してルーティング階層を作成します。

近い将来、実用的なデモを含めるように努めます。

クレジットは@ karl-agiusにも送られます。

4
Kevin Farrugia

私は正確な問題についてブログ投稿を書きました: http://fadeit.dk/post/angular-translate-ui-router-seo

2
ozooner

NgRouteを使用してURLを含めたい人のために(私は正確にそれのためにここに来ました)、私はそれを次のように実装しました。

(1).htaccessで、言語サブドメインなしですべてのURLをキャッチし、デフォルト(私の場合はfr)にリダイレクトしました。唯一の欠点は、すべての言語を手動で指定する必要があることです。

# 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)my Angularプロジェクトのconfigブロックで、URLを解析して現在の言語を取得しました。

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)HTMLファイルで言語を取得するために、$rootScopeにも追加しました。

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

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