Cuidado con los `:` al final de una traducción con el binding `translate`
Recién se detectó un problema que estaba teniendo con una traducción en el checkout de Magento, algo tan sencillo como esto <div class="step-title" translate="'Shipping Address:'" data-role="title" />
, a simple vista parece que está todo bien.. un <div />
con su clase, su atributo data-role
y su traducción con el binding, pero.. ¿qué ocurre con esto?
Si esa misma línea la ponemos en cualquier .html
veremos el siguiente error:
Esto es debido a los :
que hemos añadido al final de la traducción, pero ahora bien, esto solo pasa si utilizamos el binding translate
, si en su defecto usamos i18n
no ocurrirá. Veamos la diferencia y por qué pasa esto.
La consola nos avisa, nos dice que hay un problema al generar el binding, si bien vemos el i18n
vemos que tiene lo siguiente:
app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/i18n.js
El mismo i18n
está llamando al JS definido renderer
que haga un addAttribute
de translate y que este atributo sea un binding de i18n
para que tanto el atributo como el binding hagan lo mismo y realicen una traducción de lo que le pasemos. (Un atributo o un nodo, ambos válidos).
Ahora nos iríamos al siguiente fichero:
app/code/Magento/Ui/view/base/web/js/lib/knockout/template/renderer.js
Este fichero se encargará de hacer lo que he comentado antes, pero, nos iremos a una función en concreto:
Esta es la parte que nos está generando el error, si hacemos debug con Chrome veamos que es lo que llega y que hace.
Llega a la función attribute
con los siguientes datos:
Como vemos, nos llega el string
a traducir y el atributo translate con el binding a "provocar", cuando este llama a la función wrapArgs
, vemos que, a diferencia de por ejemplo este:
Nuestra traducción con los :
nos devuelve la traducción de esta forma:
Esto, ¿qué provoca?, cuando la traducción llega al createBindingsStringEvaluator
para crear el binding vemos los siguiente:
El rewrittenBindings
devuelve el i18n
pero el return de la función es un objeto, esto es lo que provoca el error de Knockout. Si vemos un ejemplo "correcto":
Aquí el return
de la función sería lo esperado, un string
el cual luego convertir.
Este caso es muy difícil que se de en un Magento2 mientras desarrollamos, y es más, si vemos que esto nos falla lo más normal es utilizar i18n
pero quería aprovechar esto para explicar el funcionamiento del renderer para ver como magento aprovecha un atributo para generar un binding de KO.