angularjs - ng2 - ngx-translate angular 4
Localice las URL con ui-router y angular-translate (4)
He escrito una entrada de blog sobre el asunto exacto: http://fadeit.dk/post/angular-translate-ui-router-seo
Estoy usando ui-router para enrutamiento y traducción angular para traducciones. Lo que me gustaría lograr es tener el enlace del idioma seleccionado a la url así:
www.mydomain.com/en/
www.mydomain.com/ru/
www.mydomain.com/en/about
www.mydomain.com/ru/about
y responderá en consecuencia.
Intenté buscar ejemplos, pero no encontré nada. Si alguien implementara una solución similar, me encantaría saber cómo lo hiciste.
Gracias
La solución solo es válida si desea tener URL con el formato siguiente:
domain.com/{locale}/about
por lo tanto:
domain.com/en/about domain.com/mt/about
Recientemente se nos requirió implementar traducciones para la URL completa, por lo tanto:
domain.com/{locale}/{about}
donde {about}
se traduce en el idioma respectivo:
domain.com/en/about domain.com/mt/fuqna
No sé si el enfoque de abajo es el mejor, sin embargo, funciona.
Para empezar, la primera diferencia es que configuramos los estados de ui-router para que se generen dinámicamente usando un servicio que recupera las rutas de un archivo JSON. Esto se hace de manera similar a la respuesta de @ ChrisT en: Angular - UI Router - agregar estados programáticamente
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;
}]);
Entonces consumiríamos el servicio de routingService
anterior en el bloque de run
de la aplicación:
// 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);
}
});
}
]);
Y finalmente, el servicio de stateService
simplemente analiza el archivo JSON y crea la jerarquía de enrutamiento utilizando runtimeStates.addState de ChrisT.
Intentaré incluir una demostración de trabajo en un futuro próximo.
Los créditos también van a @ karl-agius.
Para las personas que deseen incluir la URL usando ngRoute (vine aquí en Google para exactamente eso), la he implementado de la siguiente manera.
(1) En mi .htaccess
, capturé todas las URL sin un subdominio de idioma y lo redirigí al valor predeterminado (fr en mi caso). El único inconveniente real es que tengo que especificar cada idioma manualmente.
# https://.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) En el bloque de config
mi proyecto Angular, simplemente analicé la URL para obtener el idioma actual.
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) Para obtener el idioma en mis archivos HTML, también lo agregué a $rootScope
.
run.$inject = [''$window'', ''$rootScope''];
function run($window, $rootScope ) {
$rootScope.language = $window.location.pathname.replace(////g, '''');
}
Yo uso algo en este sentido:
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 esto, puede inyectar $stateParams
en su controlador y obtener acceso a la configuración regional allí:
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;
}
]);
O, si desea afectar a toda la página automáticamente, use el evento $stateChangeStart
en un controlador de aplicación o similar:
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);
});
Tenga en cuenta que si está usando angular-translate v1.x, debe usar $translate.uses
lugar de $translate.use
.