I am using ui-router for routing and angular-translate for translations. What i would like to achieve is having the selected language bind to the url like so:
www.mydomain.com/en/ www.mydomain.com/ru/ www.mydomain.com/en/about www.mydomain.com/ru/about
and it will respond accordingly.
Tried to look for examples, but did not find anything. If someone implemented similar solution, i would love to hear how you did it.
Thanks
I use something along these lines:
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' }); } ]);
With this, you can inject $stateParams
into your controller and get access to the locale there:
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; } ]);
Or, if you want to affect the whole page automatically, use the $stateChangeStart
event in an application controller or 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); });
Note that if you're using angular-translate v1.x you should use $translate.uses
instead of $translate.use
.
The solution is valid only if you want to have URLs of the below format:
domain.com/{locale}/about
hence:
domain.com/en/about domain.com/mt/about
Recently we were required to implement translations for the full URL, therefore:
domain.com/{locale}/{about}
where {about}
is translated in the respective language:
domain.com/en/about domain.com/mt/fuqna
I don't know if the below approach is the best one, however it does work.
For starters, the first difference is that we set up ui-router states to be generated dynamically using a service which retrieves the routes from a JSON file. This is done similarly to @ChrisT's answer 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; }]);
We would then consume the above routingService
in the run
block of the application:
// 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); } }); } ]);
And finally the stateService
simply parses the JSON file and creates the routing hierarchy using ChrisT's runtimeStates.addState.
I will try to include a working demo in the near future.
Credits also go to @karl-agius.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With