I've noticed strange-to-me "sigil strings" strewn throughout Magento 2's RequireJS modules. Here's one example.

return Element.extend({
    defaults: {
        clientConfig: {
            urls: {
                save: '${ $.submit_url }',
                beforeSave: '${ $.validate_url }'
            }
        }
    },

Does anyone know what these strings (${ $.submit_url }, ${ $.validate_url }) are for? Is it some Magento meta-programming language? Or are they something executed in Knockout.js context? Or something else?

  • It's used by jQuery Template Plugin - stackoverflow.com/questions/13907924/… – igloczek Sep 22 '16 at 17:17
  • @BartekIgielski Are you sure that's what it is in Magento 2? There's two nested level of sigils. I don't see that in your link. – Alan Storm Sep 22 '16 at 18:33
  • Sorry, I though they use it, but looks like there is a Magento custom implementation of Underscore.js templating engine created in lib/web/mage/utils/template.js and some kind of documentation is inside that file. Hope that may help you somehow :) – igloczek Sep 22 '16 at 19:23
up vote 11 down vote accepted

They are template literals that Magento handles itself to enhance browser compatibility.

In ES2015, template literals can be done with back-ticks (``). However, since not all browsers support that, Magento opted to process them by itself. This is done upon initialization of Javascript components in the mage/utils/template.js file. Specifically, the initConfig() method of lib/core/class.js transfers the defaults property into class properties and runs the template() method on each one.

If the browser supports ES2015-style template literals, then Magento simply uses backticks to process the string. If not, it manually evaluates the expression.

The expression inside the ${ } ($.submit_url in your example), is evaluated as a key from the config data that is passed into the JSON representing the UI Component. From what I've seen, this is usually declared in the form of js_config or just config in an XML <argument /> node (see ui_component/category_form.xml).

They are evaluated in KnockoutJS context with the $ representing the Knockout object that relates to that component.

Sidenote: I just wrote some information on that in a topic that I created a PR for the devdocs on.

  • Thanks @bassplayer7 -- super helpful. It's also worth noting that the $.submit_url variable/placeholder inside the ${} variable/placeholder markers is not (to my knowledge) standard ES 6 template literal code, and instead an addition Magento made that's able to read from a bound object of view variables (from the constructor's defaults), or an object passed into the constructor at instantiation time. – Alan Storm Sep 30 '16 at 21:17
  • @AlanStorm, glad it was helpful. My understanding is that expressions inside template literals can be just about anything, though. Magento makes the $ reference the Knockout context and, as a result, when Javascript evaluates the expression, it accesses the submit_url property of the $ variable. – bassplayer7 Oct 1 '16 at 2:07
  • Its my understanding the ES6 placeholders can us any variable in the current scope. Magento's literals, implemented by the mage/utils/template RequireJS library, can only read form the global scope, or from a specific bound object. i.e. (requirejs('mage/utils/template').template(${$.foo}, {'foo':'hello!'}). Magento binds the second argument as $ inside the placeholder. So it's probably more accurate for me to say Magento's use of ES6 literals is standard, but they've (at some level) created a new system that extends their capabilities into non-standard territory. – Alan Storm Oct 1 '16 at 4:10

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.