Reputation: 651
I am working on localizing my durandal application. I have already chosen an approach - I am sharing a module across all my pages containing all the strings that any view may have.
In my shell I am defining
router.map([
{ route: ['', 'search'], title: i18n.search, moduleId: 'viewmodels/search/index', nav: true },
{ route: "employees", title: i18n.employeesList, moduleId: "viewmodels/employees/index", nav: false },
{ route: "details/:id", title: i18n.details, moduleId: "viewmodels/details/index", nav: false }
// ...
]);
where the i18n
properties are ko.observables containing strings like
i18n = {
search: ko.observable("search"),
employeesList: ko.observable("employeesList"),
details: ko.observable("Details")
}
This works fine printing my navigation bar with
<ul class = "nav navbar-nav" data-bind = "foreach: router.navigationModel">
<li data-bind = "css: { active: isActive }">
<a data-bind = "attr: { href: hash }, text: title"></a>
</li>
</ul>
however when it comes to having the document title changed, it does not work.
Here I found something about durandal setting the document.title, unfortunately the answer suggests that to change the title durandal creates some other properties (that seem to be based on my title
module object declaration property) and probably does not assume that the title
might be something other than a string.
Is there a way to override some method that durandal uses to change the document.title or any other way to make it change document.title when navigating?
Upvotes: 1
Views: 901
Reputation: 61
This might come a little late, but I'd like to add my solution too :-) I am using observables which change the text of my variables on demand. When setting the routes and their options like this:
var routes = [{ route: '', title: 'Welcome', moduleId: 'viewmodels/welcome', nav: true, title:
ko.computed(function () { return activeTranslation.welcome() })
}];
my activeTranslation looks something like this:
var activeTranslation = {
welcome: ko.observable()
}
Now when changing the language I just have to loop through my language object containing the same variables and their respective translation and apply them to the observable.
var dutch = { welcome: "Welkom" };
function loadLanguage (lang) {
for (var key in languages[lang]) {
activeTranslation[key](languages[lang][key]);
}
}
Upvotes: 2
Reputation: 3723
You can follow the steps outlined in Durandal.js 2.0 Set document title within activate method.
You'd need to overwrite router.updateDocumentTitle
in main.js|shell.js so that it takes into account that config.title
is an observable.
Something along the following should get you started.
router.updateDocumentTitle = function(instance, instruction) {
if (instruction.config.title) {
if (app.title) {
document.title = ko.unwrap(instruction.config.title) + " | " + app.title;
} else {
document.title = ko.unwrap(instruction.config.title);
}
} else if (app.title) {
document.title = app.title;
}
};
Update: Based on comment.
In addition to the modification above if the title should change immediately then there's some more work required.
Reason is that router doesn't know about language switching. Pub/sub is most probably the right way for the implementation. Consider setting up an event e.g using app.on
that changes the document.title. router.activeInstruction()
will provide access to the config object. Trigger the event whenever somebody is switching in whatever view model.
Upvotes: 4