Magento 2 – How to Translate Knockout String Variables

knockoutjslocalisationmagento2

I'm extending and translating a third party module which has the following in a template:

<!--ko foreach: options-->
<div class="option">
    <label data-bind="i18n: label"></label>
</option>
<!-- /ko -->

The label variable pulls in three attributes in a loop, but because there is no literal string value declared – the dictionary does not pick it up and any attempts to translate the value label returns are ignored.

I have hacked it by doing the following:

<label data-bind="i18n: 'Back Dimensions'" style="display:none;"></label>
<label data-bind="i18n: 'Top Dimensions'" style="display:none;"></label>
<label data-bind="i18n: 'Circumference'" style="display:none;"></label>

<!--ko foreach: options-->
<div class="option">
    <label data-bind="i18n: label"></label>
</option>
<!-- /ko -->

So here the translations are picked up because the literal strings to be translated are declared in the template and picked up by the dictionary parser.

But I'm curious what is the correct approach to this…

Best Answer

As far as I know there is no proper way to translate dynamic strings in JavaScript. The best approach probably is to translate the option labels on the server with __() before they get into JS.

For example you could add them to the $.mage.translate instance in the .phtml template with something like this (untested):

<script>
require([‘jquery’, ‘mage/translate’], ($) => {
<?php foreach ($options as $label): ?>
    $.mage.translate.add(
        ‘<?= $block->escapeJs($label) ?>’,
        ‘<?= $block->escapeJs(__($label)) ?>’
    );
<?php endforeach ?>
});
</script>