Default and Core Handles
Handle Types
| Handle | Example | When Loaded |
|---|---|---|
| default | default |
Every page |
| base | base |
Every page (frontend) |
| 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 |
Default Handle
Loaded on every page:
<!-- default.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>
<referenceBlock name="header" remove="true"/>
</body>
</page>
Base Handle
Also loaded on every page (frontend):
<!-- base.xml -->
<page>
<body>
<container name="root" htmlTag="div" htmlClass="page-wrapper">
<block class="Magento\Theme\Block\Html\Header" name="header"/>
<block class="Magento\Theme\Block\Html\Footer" name="footer"/>
</container>
</body>
</page>
Route Handles
Format: {area}_{route}_{controller}_{action}
Examples:
cms_index_index— Homepagecatalog_product_view— Product pagecatalog_category_view— Category pagecheckout_index_index— Checkout page
CMS and Catalog Handles
CMS Handles
<!-- cms_index_index.xml (Homepage) -->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"
layout="1column">
<body>
<referenceContainer name="content">
<block class="Magento\Cms\Block\Block" name="homepage-banner">
<arguments>
<argument name="block_id" xsi:type="string">homepage-banner</argument>
</arguments>
</block>
</referenceContainer>
</body>
</page>
<!-- cms_page_view.xml (All CMS pages) -->
<page>
<body>
<referenceContainer name="content">
<block class="Magento\Cms\Block\Page" name="cms_page"/>
</referenceContainer>
</body>
</page>
Catalog Product Handles
<!-- catalog_product_view.xml (All product pages) -->
<page>
<body>
<referenceBlock name="product.info">
<block class="Vendor\Module\Block\Warranty" name="warranty"/>
</referenceBlock>
</body>
</page>
<!-- catalog_product_view_id_5.xml (Specific product) -->
<page>
<body>
<referenceBlock name="product.info">
<block class="Vendor\Module\Block\Special" name="special"/>
</referenceBlock>
</body>
</page>
Catalog Category Handles
<!-- catalog_category_view.xml -->
<page>
<body>
<referenceContainer name="content">
<block class="Vendor\Module\Block\CategoryWidget" name="category.widget"/>
</referenceContainer>
</body>
</page>
Custom Layout Handles
Creating Custom Handles
Via XML Layout Files
<!-- vendor_module_index.xml -->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"
layout="2columns-left">
<body>
<referenceContainer name="content">
<block class="Vendor\Module\Block\Dashboard" name="dashboard"/>
</referenceContainer>
</body>
</page>
Via Layout Processor
<?php
namespace Vendor\Module\LayoutProcessor;
use Magento\Framework\View\Layout\Argument\BuilderInterface;
class CustomHandle
{
public function process(array $layout): array
{
if ($this->isCustomPage()) {
$layout['xml'] .= '<handle name="custom_handle"/>';
}
return $layout;
}
}
Via Controller Action
public function execute()
{
$this->layout->getUpdate()->addHandle('custom_handle');
return $this->resultPageFactory->create();
}
Dynamic Handles
// Add handle based on condition
if ($this->isPreviewMode()) {
$this->layout->getUpdate()->addHandle('preview_mode');
}
// Add handle with parameters
$handle = sprintf('product_view_id_%d', $productId);
$this->layout->getUpdate()->addHandle($handle);
Handle Loading Order
Loading Priority
- default — loaded on every page
- base — loaded on every frontend page
- Area handle — e.g.,
frontend - Route handle — e.g.,
catalog_product_view - Action handle — e.g.,
catalog_product_view_id_5 - Theme handle — e.g.,
frontend_Amazon_Prep - Custom handles — added programmatically
Visual Loading Order
1. default.xml
2. base.xml
3. frontend.xml
4. catalog_product_view.xml
5. catalog_product_view_id_5.xml
6. frontend_Amazon_Prep.xml
7. custom_handle.xml (if added)
Override Behavior
Later handles override earlier ones for the same block names:
<!-- default.xml -->
<block name="product.info" class="Original\Block"/>
<!-- catalog_product_view.xml (overrides) -->
<referenceBlock name="product.info" class="Custom\Block"/>
Debugging Handles
# Enable layout hints
bin/magento dev:layout:hints:enable
# View loaded handles
bin/magento dev:layout:debug
# Check specific handle
bin/magento dev:layout:debug --handle=catalog_product_view
Quiz
1. Which layout handle is loaded on every page?
2. What is the format for route handles?
3. How do you add a custom handle programmatically?
Flashcards
Question
What handle is loaded on every page?
Click to reveal answer
Answer
default and base handles
Question
What is the route handle format?
Click to reveal answer
Answer
{area}_{route}_{controller}_{action}
Question
How do you add a custom handle?
Click to reveal answer
Answer
$this->layout->getUpdate()->addHandle('handle_name')
Question
What handle loads for the homepage?
Click to reveal answer
Answer
cms_index_index
Question
What handle loads for product pages?
Click to reveal answer
Answer
catalog_product_view
Revision Notes
Key Takeaways
- 1. default and base handles load on every page
- 2. Route handles follow area_route_controller_action format
- 3. Action handles include specific parameters like product ID
- 4. Custom handles can be added via XML or programmatically
- 5. Later handles override earlier ones
Interview Tips
- • Explain the handle loading order
- • Know the difference between default, base, and route handles
- • Be ready to create custom handles
- • Discuss when to use action handles vs route handles
Cheat Sheet
Handles loaded:
1. default (every page)
2. base (frontend pages)
3. area (frontend)
4. route (catalog_product_view)
5. action (catalog_product_view_id_5)
6. theme (frontend_Vendor_Theme)
7. custom (added programmatically)
Add custom handle:
$this->layout->getUpdate()->addHandle('custom');