Continer is similar to a block but different by three ways.

  1. Has no associated class file
  2. Has no template
  3. Has no content
// app/code/MyVendor/MyMethod/Controller/Index/Index.php

public function execute()
{
    $objectManager = $this->getObjectManager();
    $layout = $objectManager->get('Magento\Framework\View\Layout');
    $blockParent = $layout->createBlock(
                    'Magento\Framework\View\Element\Template',
                    'myvendor_mymethod_parent'
                    );
    $blockParent->setTemplate('MyVendor_MyMethod::user/parent.phtml');
    $blockChild1 = $layout->createBlock(
                    'Magento\Framework\View\Element\Template',
                    'myvendor_mymethod_child1'
                    );
    $blockChild1->setTemplate('MyVendor_MyMethod::user/child1.phtml');
    $blockParent->append($blockChild1);
    $layout->addContainer('top', 'The top level Container');

    // Magento\Framework\View\Layout\Data\Structure
    $structure = $layout->getStructure();
    $structure->setAsChild('myvendor_mymethod_parent', 'top');
    $layout->generateElement();
    echo $layout->getOutput();

}

First, we make a root level container named top. We make parent block as a child block of top container, which also has child block to parent block.

When we call getOutput from layout, it does

  1. Find every root level container added with addContainer
  2. Render every top level block inside that container
// app/code/MyVendor/MyMethod/Controller/Index/Index.php

public function execute()
{
    $objectManager = $this->getObjectManager();
    $layout = $objectManager->get('Magento\Framework\View\Layout');
    
    $updateManager = $layout->getUpdate();
    $updateManager->addUpdate('<container name="top"></container>');

    $updateManager->addUpdate(
      '<referenceContainer name="top">
           <block
               class="Magento\Framework\View\Element\Template"
               name="myvendor_mymethod_block1"
               template="MyVendor_MyMethod::user/block1.phtml">
           </block>
       </referenceContainer>'
    );
}

Layout Update is a chunk of XML, but it is not configuration, but it is DSL(Domain Specific language).
The addUpdate phpscript transforms the XML into php code as

$layout->addContainer('top', 'The top level container');

The referenceContainer would find for the container named ‘top’. The class would be the class that instantiatiating the block. The name is just a unique identifier,and the template is similar to the setTemplate method. We can also make parent/child blocks with layout XML.

public function execute()
{
    $objectManager = $this->getObjectManager();
    $layout = $objectManager->get('Magento\Framework\View\Layout');

    $updateManager = $layout->getUpdate();
    $updateManager->addUpdate('<container name="top"></container>');

    $updateManager->addUpdate(
      '<referenceContainer name="top">
           <block
               class="Magento\Framework\View\Element\Template"
               name="myvendor_mymethod_parent"
               template="MyVendor_MyMethod::user/parent.phtml">
               <block
                   class="Magento\Framework\View\Element\Template"
                   name="myvendor_mymethod_child"
                   template="MyVendor_MyMethod::user/child.phtml"
                   >
               </block>
           </block>
       </referenceContainer>'
    );
}

Also, we can pass arguments in layout update DSL.


<referenceContainer name="top">
           <block
               class="Magento\Framework\View\Element\Template"
               name="myvendor_mymethod_hello"
               template="MyVendor_MyMethod::user/hello.phtml">
               <arguments>
                   <argument name="the_message" xsi:type="string">Hello World</argument>
                   <argument name="the_array" xsi:type="array">
                       <item name="key" xsi:type="string">value</item>
                       <item name="foo" xsi:type="stirng">var</item>
                   </arguement>
               </arguments>
           </block>
       </referenceContainer>

After passing arguments, we are able to call it with getData function. We can pass string or array.