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 pagescatalog_product_view— product view pagecatalog_product_view_id_5— product with ID 5cms_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
default.xml— loaded on every page- Area-specific handles (e.g.,
catalog_product_view) - Route-specific handles (e.g.,
vendor_module_index) - Action-specific handles (e.g.,
vendor_module_index_id_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 classname: Unique identifier in layouttemplate: .phtml template fileafter/before: Sort orderoutput: If1, 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 containerhtmlId: HTML id attributeoutput: 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?
2. How do you remove a block from the layout?
3. What does the 'output="1"' attribute do on a block?
Flashcards
Question
What is a layout handle?
Click to reveal answer
Answer
An XML identifier that determines which layout configuration applies to a page
Question
What's the difference between block and container?
Click to reveal answer
Answer
Block renders content; container groups blocks and adds HTML wrapper elements
Question
How do you pass data to a block via layout XML?
Click to reveal answer
Answer
Use <arguments> with <argument name="key" xsi:type="type">value</argument>
Question
How do you override a block's class in layout?
Click to reveal answer
Answer
<referenceBlock name="..." class="New\Class\Name"/>
Question
What layout file applies to the product view page?
Click to reveal answer
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"/>