Локализовать URL-адрес с помощью ui-router и angular -translate
Я использую ui-router для маршрутизации и angular -транслят для переводов. Я бы хотел добиться того, чтобы выбранный язык привязывался к URL-адресу:
www.mydomain.com/en/
www.mydomain.com/ru/
www.mydomain.com/en/about
www.mydomain.com/ru/about
и он ответит соответствующим образом.
Пытался искать примеры, но ничего не нашел.
Если бы кто-то реализовал подобное решение, я бы хотел услышать, как вы это сделали.
Спасибо
Ответы
Ответ 1
Я использую что-то в этих строках:
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
.
Ответ 2
Решение действует только в том случае, если вы хотите иметь 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
Я не знаю, лучший ли подход ниже, но он работает.
Для начала первое отличие состоит в том, что мы настраиваем состояния ui-router, которые должны генерироваться динамически, используя службу, которая извлекает маршруты из файла JSON. Это делается аналогично @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.
Ответ 3
Я написал сообщение в блоге по точному вопросу:
http://fadeit.dk/post/angular-translate-ui-router-seo
Ответ 4
Для людей, которые хотели бы включить URL-адрес, используя ngRoute (я пришел сюда для поиска именно этого), я реализовал его следующим образом.
(1) В моем .htaccess
я поймал все URL-адреса без субдомена языка и перенаправил его по умолчанию (fr в моем случае). Единственным реальным недостатком является то, что я должен указать каждый язык вручную.
# https://stackoverflow.com/info/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) В моем проекте Angular project 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, '');
}