Skip to content
intermediate Phase 24 · Module Frontend

Layout XML - Complete Guide

Understanding Magento 2 Layout XML: handles, blocks, containers, references, arguments, and complete layout configuration examples

1h
0 problems
Topic Progress 0%

Layout Handles and Structure

What are Layout Handles?

Layout handles are XML identifiers that determine which layout configuration applies to a page. Every page loads multiple handles.

Handle Types

Handle Example When Loaded
default default Every page
core_update core_rss_index RSS feeds
route catalog_product_view Product view page
action catalog_product_view_id_5 Specific product
theme frontend_theme_name Theme-specific

Handle Naming Convention

{area}_{route}_{controller}_{action}[_param_value]

Examples:

  • frontend_default — all frontend pages
  • catalog_product_view — product view page
  • catalog_product_view_id_5 — product with ID 5
  • cms_index_index — CMS homepage

Layout File Locations

view/frontend/layout/
├── default.xml                    (all pages)
├── catalog_product_view.xml       (product page)
├── catalog_category_view.xml      (category page)
├── cms_index_index.xml            (homepage)
└── vendor_module_index.xml        (custom route)

Layout Loading Order

  1. default.xml — loaded on every page
  2. Area-specific handles (e.g., catalog_product_view)
  3. Route-specific handles (e.g., vendor_module_index)
  4. Action-specific handles (e.g., vendor_module_index_id_5)
  5. Theme layout overrides

Later handles override earlier ones for the same block names.

Blocks, Containers, and References

Block Element

Adds a block to the layout:

<block class="Amazon\Prep\Block\ProductList"
       name="amazon.product.list"
       template="Amazon_Prep::product/list.phtml"
       after="-"
       before="-"
       output="1"/>

Attributes:

  • class: Block PHP class
  • name: Unique identifier in layout
  • template: .phtml template file
  • after/before: Sort order
  • output: If 1, renders automatically

Container Element

Groups blocks together:

<container name="amazon.prep.container" htmlTag="div" htmlClass="prep-wrapper">
    <block class="Amazon\Prep\Block\Header" name="header" template="header.phtml"/>
    <block class="Amazon\Prep\Block\Content" name="content" template="content.phtml"/>
</container>

Container attributes:

  • htmlTag: HTML element tag (div, section, etc.)
  • htmlClass: CSS class for the container
  • htmlId: HTML id attribute
  • output: Render automatically

ReferenceBlock

Modifies an existing block:

<!-- Add content to existing block -->
<referenceBlock name="product.info">
    <block class="Amazon\Prep\Block\WarrantyInfo"
           name="warranty.info"
           template="warranty/info.phtml"
           after="product.info.form"/>
</referenceBlock>

<!-- Remove a block -->
<referenceBlock name="product.info.review" remove="true"/>

<!-- Change block class -->
<referenceBlock name="product.info" class="Amazon\Prep\Block\CustomProductInfo"/>

<!-- Change template -->
<referenceBlock name="product.info" template="Amazon_Prep::product/custom.phtml"/>

ReferenceContainer

Modifies an existing container:

<referenceContainer name="content">
    <container name="amazon.prep" htmlTag="div" htmlClass="prep-section">
        <block class="Amazon\Prep\Block\Widget" name="widget" template="widget.phtml"/>
    </container>
</referenceContainer>

Body References

<page>
    <body>
        <!-- Before body content -->
        <referenceContainer name="before.body.end">
            <block class="Amazon\Prep\Block\Analytics" name="analytics" template="analytics.phtml"/>
        </referenceContainer>

        <!-- After body content -->
        <referenceContainer name="after.body.end">
            <block class="Amazon\Prep\Block\Chat" name="chat" template="chat.phtml"/>
        </referenceContainer>
    </body>
</page>

Arguments and Data Passing

Passing Arguments to Blocks

<block class="Amazon\Prep\Block\ProductList"
       name="product.list"
       template="product/list.phtml">
    <arguments>
        <!-- String argument -->
        <argument name="title" xsi:type="string">Featured Products</argument>

        <!-- Number argument -->
        <argument name="limit" xsi:type="number">10</argument>

        <!-- Boolean argument -->
        <argument name="show_price" xsi:type="boolean">true</argument>

        <!-- Array argument -->
        <argument name="categories" xsi:type="array">
            <item name="0" xsi:type="number">10</item>
            <item name="1" xsi:type="number">20</item>
            <item name="2" xsi:type="number">30</item>
        </argument>

        <!-- Object argument -->
        <argument name="config" xsi:type="object">Amazon\Prep\Model\Config</argument>
    </arguments>
</block>

Accessing Arguments in Block

class ProductList extends Template
{
    public function getTitle(): string
    {
        return $this->getData('title');
    }

    public function getLimit(): int
    {
        return (int)$this->getData('limit');
    }

    public function shouldShowPrice(): bool
    {
        return (bool)$this->getData('show_price');
    }

    public function getCategories(): array
    {
        return $this->getData('categories');
    }
}

Overriding Arguments

Child handles can override parent arguments:

<!-- default.xml -->
<block class="Amazon\Prep\Block\Widget" name="widget" template="widget.phtml">
    <arguments>
        <argument name="title" xsi:type="string">Default Title</argument>
    </arguments>
</block>

<!-- catalog_product_view.xml (overrides the title) -->
<referenceBlock name="widget">
    <arguments>
        <argument name="title" xsi:type="string">Product Page Widget</argument>
    </arguments>
</referenceBlock>

Remove Arguments

<referenceBlock name="widget">
    <arguments>
        <!-- Remove specific argument -->
        <argument name="title" xsi:type="null"/>
    </arguments>
</referenceBlock>

Complete Layout Examples

Custom Page Layout

<!-- vendor_module_index.xml -->
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"
      layout="2columns-left">

    <update handle="formkey"/>

    <body>
        <referenceContainer name="content">
            <block class="Amazon\Prep\Block\Dashboard"
                   name="dashboard"
                   template="dashboard.phtml">
                <arguments>
                    <argument name="title" xsi:type="string">Prep Dashboard</argument>
                    <argument name="show_sidebar" xsi:type="boolean">true</argument>
                </arguments>
            </block>
        </referenceContainer>

        <referenceContainer name="sidebar.main">
            <block class="Amazon\Prep\Block\Sidebar"
                   name="sidebar"
                   template="sidebar.phtml"/>
        </referenceContainer>
    </body>
</page>

Adding to Product Page

<!-- catalog_product_view.xml -->
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">

    <body>
        <!-- Add warranty info after product price -->
        <referenceBlock name="product.info">
            <block class="Amazon\Prep\Block\Warranty"
                   name="product.warranty"
                   template="warranty.phtml"
                   after="product.info.price"/>
        </referenceBlock>

        <!-- Add prep info to product tabs -->
        <referenceContainer name="product.info.detailed">
            <container name="product.info.tabs" htmlTag="div" htmlClass="product-tabs">
                <block class="Amazon\Prep\Block\Tab"
                       name="tab.prep"
                       template="tab/prep.phtml">
                    <arguments>
                        <argument name="title" xsi:type="string">Prep Information</argument>
                        <argument name="sort_order" xsi:type="number">50</argument>
                    </arguments>
                </block>
            </container>
        </referenceContainer>

        <!-- Remove reviews tab if not needed -->
        <referenceBlock name="reviews.tab" remove="true"/>
    </body>
</page>

Layout XML Processors

For dynamic layout changes, use layout processors:

<?php
namespace Amazon\Prep\Layout;

class ProductViewProcessor implements \Magento\Framework\View\Layout\ProcessorInterface
{
    public function process(array $layout): array
    {
        if (isset($layout['catalog_product_view']['body']['referenceContainer']['product.info'])) {
            $layout['catalog_product_view']['body']['referenceContainer']['product.info']['block']['product.warranty'] = [
                'class' => 'Amazon\Prep\Block\Warranty',
                'template' => 'warranty.phtml',
            ];
        }
        return $layout;
    }
}

Register in di.xml:

<type name="Magento\Framework\View\Layout\ProcessorInterface">
    <plugin name="amazon_prep_layout" type="Amazon\Prep\Layout\ProductViewProcessor"/>
</type>

Quiz

1. What layout handle is loaded on every page?

Question 1 options

2. How do you remove a block from the layout?

Question 2 options

3. What does the 'output="1"' attribute do on a block?

Question 3 options

Flashcards

Question

What is a layout handle?

Answer

An XML identifier that determines which layout configuration applies to a page

Question

What's the difference between block and container?

Answer

Block renders content; container groups blocks and adds HTML wrapper elements

Question

How do you pass data to a block via layout XML?

Answer

Use <arguments> with <argument name="key" xsi:type="type">value</argument>

Question

How do you override a block's class in layout?

Answer

<referenceBlock name="..." class="New\Class\Name"/>

Question

What layout file applies to the product view page?

Answer

catalog_product_view.xml

Revision Notes

Key Takeaways

  • 1. Layout handles determine which XML applies: default → route → action
  • 2. Blocks render content; containers group blocks with HTML wrappers
  • 3. ReferenceBlock/Container modify existing elements; remove deletes them
  • 4. Arguments pass data from layout XML to block classes
  • 5. Layout processors allow programmatic layout modification

Interview Tips

  • Explain the layout handle loading order
  • Know the difference between block, container, and referenceBlock
  • Be ready to write layout XML for a custom page
  • Discuss when to use layout processors vs static XML

Cheat Sheet

Handles: default → route → action → theme

Elements:
  block → renders content
  container → groups blocks + HTML wrapper
  referenceBlock → modify existing block
  referenceContainer → modify existing container

Arguments:
  <argument name="key" xsi:type="string">value</argument>

Remove: <referenceBlock name="..." remove="true"/>