I'm modifying a template in magento2, which have this chunk of code:
<a href="#"
class="item-action action-gift"
data-bind="
attr: {title: 'Gift Options'}
">
<span data-bind="i18n: 'Gift options'"></span>
</a>
I want to be able to translate the title attribute like so
<a href="#"
class="item-action action-gift"
data-bind="
attr: {title: i18n:'Gift Options'}
">
<span data-bind="i18n: 'Gift options'"></span>
</a>
But that obviously gives error. Is it possible to have i18n in the attr binding? How to do it properly if it is?
You can create a custom binding handler that calls a default binding by using ko.applyBindingsToNode.
To inject your i18n translation step, you create a ko.pureComputed representation of your settings object inside the init method and call the original attr binding with it.
Say we have a function named i18n that takes a string and returns another string. We'll go from:
attr: { title: "my string" }
To
attr: { title: i18n("my string") }
Here's how we create the computed object that is passed to attr:
ko.bindingHandlers.i18nAttr = {
init: function(el, va) {
var translated = ko.pureComputed(function() {
// Support observable options objects: unwrap
var options = ko.unwrap(va());
return Object
.keys(options)
.reduce(function(tOptions, k) {
// Support observable properties: unwrap
tOptions[k] = i18n(ko.unwrap(options[k]));
return tOptions;
}, {});
});
return ko.applyBindingsToNode(el, { attr: translated });
}
};
In a working example: (I created a computed i18n function to support toggling on and off translations/switching languages)
ko.bindingHandlers.i18nAttr = {
init: function(el, va) {
var translated = ko.pureComputed(function() {
var options = ko.unwrap(va());
var translate = i18n();
return Object
.keys(options)
.reduce(function(tOptions, k) {
tOptions[k] = translate(ko.unwrap(options[k]));
return tOptions;
}, {});
});
return ko.applyBindingsToNode(el, { attr: translated });
}
};
var translate = ko.observable(true);
var i18n = translater(translate);
var vm = {
title: "Elevator",
placeholder: "Cookie",
translate: translate
};
ko.applyBindings(vm);
// Mock i18n method
function translater(doTranslate) {
return ko.pureComputed(function() {
return doTranslate()
? function(str) { return str; }
: function(str) {
return ({
"Elevator": "Lift",
"Cookie": "Biscuit"
})[str];
};
});
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<input data-bind="i18nAttr: { placeholder: placeholder }"/>
<a data-bind="i18nAttr: { title: title }">hover for title</a>
<label><input type="checkbox" data-bind="checked: translate">Translate</label>
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