cancel
Showing results for 
Search instead for 
Did you mean: 

What are the “source” Items in UI Component Files

What are the “source” Items in UI Component Files

In Magento 2's UI Form Component configuration files, you'll often see a item attribute with the same of source -- <item name="source" xsi:type="string">block</item> below.

 

#File: vendor/magento/module-cms/view/adminhtml/ui_component/cms_block_form.xml
<field name="title">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="dataType" xsi:type="string">text</item>
            <item name="label" xsi:type="string" translate="true">Block Title</item>
            <item name="formElement" xsi:type="string">input</item>
            <item name="source" xsi:type="string">block</item>
            <item name="sortOrder" xsi:type="number">20</item>
            <item name="dataScope" xsi:type="string">title</item>
            <item name="validation" xsi:type="array">
                <item name="required-entry" xsi:type="boolean">true</item>
            </item>
        </item>
    </argument>
</field>

 

What are these fields for? I ask because it seems like they're not necessary. I can create a UI Form Component without them and everything works (see https://github.com/astorm/magento2-pestle-platonic-module-output)

 

Does anyone know what these name="source" items are for? I'm aware of the UI Component mechanic that takes the XML and configures it as x-magento-init JSON that looks something like this

 

"block_id": {
    "type": "form.input",
    "name": "block_id",
    "dataScope": "block_id",
    "config": {
        "component": "Magento_Ui\/js\/form\/element\/abstract",
        "template": "ui\/form\/field",
        "visible": false,
        "dataType": "text",
        "formElement": "input",
        "source": "block"
    }
},

This JSON is fed into a uiElement based Knockout view model object. However, it's not clear how the nested tree of uiElement based Knockout view model objects use these field level source fields.

 

If I look at the uiElement's initModules method

 

    initModules: function () {
        _.each(this.modules, function (name, property) {
            if (name) {
                this[property] = this.requestModule(name);
            }
        }, this);

        if (!_.isFunction(this.source)) {
            this.source = registry.get(this.provider);
        }

        return this;
    },

I see the object references a source property, and if its not set, will reach into the registry for an object using the provider property as a string/key identifier. It seems like the value of these source items isn't used. However, its possible that they're used by the PHP code, or some other javascript code. Hence, my question.

5 REPLIES

Re: What are the “source” Items in UI Component Files

The "source" property declared in XML uses backend DataProviders that support multiple data section.
The value of this property is name of the section that backend DataProvider adds to the resulting data object.
The JS "source" property is generated automatically using the "provider" property as a link to JS DataSource.

Re: What are the “source” Items in UI Component Files

Thank you for the reply 

 

 

    #File: vendor/magento/module-cms/view/adminhtml/ui_component/cms_page_form.xml

 

This file contains XML that looks like this (i.e. includes a name="source" node with a value of "pages")

 

    <field name="content">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="label" xsi:type="string"/>
                <item name="formElement" xsi:type="string">wysiwyg</item>
                <item name="source" xsi:type="string">page</item>
                <item name="wysiwyg" xsi:type="boolean">true</item>
                <item name="dataScope" xsi:type="string">content</item>
                <item name="additionalClasses" xsi:type="string">admin__field-wide</item>
            </item>
        </argument>
    </field>

You said 

 

The "source" property declared in XML uses backend DataProviders that support multiple data section.

 

However, if I look at the data provider class, I don't see any multiple data sections being generated

 

    #File: vendor/magento/module-cms/Model/Page/DataProvider.php
    public function getData()
    {
        if (isset($this->loadedData)) {
            return $this->loadedData;
        }
        $items = $this->collection->getItems();
        /** @var $page \Magento\Cms\Model\Page */
        foreach ($items as $page) {
            $this->loadedData[$page->getId()] = $page->getData();
        }

        $data = $this->dataPersistor->get('cms_page');
        if (!empty($data)) {
            $page = $this->collection->getNewEmptyItem();
            $page->setData($data);
            $this->loadedData[$page->getId()] = $page->getData();
            $this->dataPersistor->clear('cms_page');
        }

        return $this->loadedData;
    }    

I can confirm this by navigating to the CMS page form and looking at the rendered data via the javascript console.  Based on what you said, I'd expect to see a "page" key in this logged object

 

console.log(requirejs('uiRegistry').get('cms_page_form.page_form_data_source').data)

However, I do not.  Additionally, per this post, it seems like  a UI Form Components uses the `dataScope` property (not source) to fetch values from a nested data provider array.  

 

Finally, the only reference we've been able to find to the source property is in the base uiElement class/constructor function.  

 

//File: vendor/magento//module-ui/view/base/web/js/lib/core/element/element.js

if (!_.isFunction(this.source)) {
    this.source = registry.get(this.provider);
}

However, as it's not possible (I think?) to have a value from the UI Component XML serialized as a javascript function, the `source` property of a serialized element will always trigger the inner if. 

 

 

Can you point to anywhere in Magento's code base where these item name="source" properties are actually used?  In other words, it seems like leaving them out doesn't change the behavior of the system in any meaningful way.  However, given Magento's -- size? -- I'm not confidant saying that for sure. 

 

 

 

Does that make sense?  i.e. do you see my confusion?  Is there anything you can do to clarify things? Thank you for your time/attention!

 

Tags (2)

Re: What are the “source” Items in UI Component Files

Bumping like it's 2002.  Any update here, or have I correctly identified that the source items in an XML configuration file aren't actually used for anything in current versions of Magento 2. 

Re: What are the “source” Items in UI Component Files

First of all it's important to understund that the are two different source properties that should be not confused.

1) All components that are inherited from uiElement class generate "source" property (currently in element.js)
The "source" property is used as direct referens to component's provider:
this.provider is just path to provider (declared as string)
this.source is provider instance itself which has "get", "set", "trigger" methods.
(It allows to avoid using "registry "in component class)
As example:

 

var addressData = this.source.get('shippingAddress');


Here we are expecting that "dataSource" has some value stored for "shippingAddress"(has "shippingAddress" property), and we are fetching it.
you can see this in "getEstimationInfo" method in

app/code/Magento/Checkout/view/frontend/web/js/view/cart/shipping-estimation.js

By default this.source property is null (that is declared in uiElements "defaults" object)

defaults: {
      source: null
}

 

 

We can't configurate "source" property in XML, because that will be always overridden in JS class (uiElement).

 

if (!_.isFunction(this.source)) {
      this.source = registry.get(this.provider);
}


We have only one ability to change source property in JS class.
For example, see column.js

(app/code/Magento/Ui/view/base/web/js/grid/columns/column.js)

modules: {
     source: '${ $.provider }'
}

 

2) The "source" property that is declared in XML file was probably used in PHP code.
Currently, as result of my investigation, the "source" property in fields in xml is redundant (is not parsed anywhere in the code).
I am 99% sure in this property useless (I've removed "source" in ... and run tests: nothing changed)

 

Re: What are the “source” Items in UI Component Files

Thanks for clearing this up (I guess...)

 

I've always been wondering what those mysterious source-elements were good for. But now I'm guessing they're redundant?