I just wanted to know how to pass argumnet from layout to block and how its work and how its value pass in $data? Can anyone explain it deeply
2 Answers
First let's see an example. I have below a simple layout snippet that assigns to a custom block an argument whose name is viewModel
.
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="content">
<block name="attribute_in_js" template="Mbs_ProductAttribute::example_attribute.phtml">
<arguments>
<argument name="viewModel" xsi:type="object">Mbs\ProductAttribute\ViewModel\ProductAttributeViewModel</argument>
</arguments>
</block>
</referenceBlock>
</body>
</page>
Technically, the above is sufficient to assign the argument viewModel
to my custom block. Then, to use the argument, you may call in your template the line $viewModel = $block->getData('viewModel');
and in your template you will have an object and its class will be Mbs\ProductAttribute\ViewModel\ProductAttributeViewModel
Now, your question is how can I check this with a deep understanding of the steps that make this happening. So, I have also selected a list of steps that you may want to set breakpoints at; you will be able to see by yourself how from xml (the argument
node particularly) we get an object in the case of my example (please notice that if the layout snippet part <argument name="viewModel" xsi:type="object">
was <argument name="viewModel" xsi:type="string">
we would have in our template a string)
If you want to see where the mapping from argument to data happens, the function to check that is deep is:
\Magento\Framework\View\Layout\Generator\Block::createBlock
Within this function, you see how the arguments
attribute is mapped to data
$block = $this->createBlock(
$className,
$elementName,
[
'data' => $this->evaluateArguments($data['arguments'])
]
);
If you want to understand the process more in depth, the steps that leads to this function are in chronological order:
step 1: the layout loading process starts
\Magento\Framework\View\Layout\Builder::build
before this function above gets called, you can add layout handles still and it is something to remember even though it is not so much relevant for the point we are looking here
step 2: the layout has already loaded the layout handles and now we are generating the block objects
\Magento\Framework\View\Layout\Builder::generateLayoutBlocks
\Magento\Framework\View\Layout::generateElements
(in this function, the line $result = $this->cache->load($cacheId);
will check if the block is cached or not. To see what's happening in a particular block, you need both full_page cache disabled and the block not to use a cache property)
\Magento\Framework\View\Layout\Reader\Block::scheduleBlock
\Magento\Framework\View\Layout\ScheduledStructure::setStructureElementData
\Magento\Framework\View\Layout\GeneratorPool::process
\Magento\Framework\View\Layout\GeneratorPool::buildStructure
the above are not fundamental. Yet, they show how the xml is extracted and the layout builds a massive array of scheduled elements
step 3: zoom on generating a specific block
\Magento\Framework\View\Layout\Generator\Block::generateBlock
-
-
pleased that you have benefited from it, thank you for your update Commented Sep 12, 2022 at 15:22
You can pass it like attribute.
{{block class='Magento\\Framework\\View\\Element\\Template' area='frontend' template='Test_Email::intro.phtml' intro='invoice_new' order_increment_id=$order.increment_id order=$order.id }}
i have created variable's order_increment_id and order.
Now i can use it's value in block with direct data.
$order_id = $this->getData('order');
$order_id = $this->getData('order_increment_id');
-
-
-
Do you have any solution related this issue please check my question magento.stackexchange.com/questions/359927/…– MarkCommented Sep 15, 2022 at 11:35