Block Architecture
What Blocks Do
Blocks bridge the gap between PHP logic and HTML templates. They prepare data, handle business logic, and pass variables to .phtml template files for rendering.
Block Directory Structure
Vendor/Module/Block/
├── Product/
│ ├── View.php → handles product view page
│ ├── List.php → handles product list
│ └── Price.php → renders price display
├── Category/
│ └── View.php
└── Widget/
└── CustomWidget.php
Block Class Hierarchy
Magento\Framework\View\Element\AbstractBlock
├── Magento\Framework\View\Element\Template
│ └── Your\Module\Block\ClassName
└── Magento\Framework\View\Element\Text
Most blocks extend Template which provides template rendering capabilities.
Basic Block Class
namespace Vendor\Module\Block\Product;
use Magento\Framework\View\Element\Template;
class View extends Template
{
public function __construct(
Template\Context $context,
array $data = []
) {
parent::__construct($context, $data);
}
public function getProductName(): string
{
return $this->_registry->registry('current_product')->getName();
}
}
Block vs ViewModel
| Aspect | Block | ViewModel |
|---|---|---|
| Lifecycle | Per-page-render | Injected via DI |
| Caching | Built-in support | Manual caching |
| Template access | Direct | Via accessor |
| Use case | Legacy pattern | Modern pattern |
Both patterns are valid. Blocks are more common in existing Magento code.
Template Rendering and Data Passing
Setting the Template
In layout XML:
<block class="Vendor\Module\Block\Product\View"
name="vendor.product.view"
template="Vendor_Module::product/view.phtml"/>
Or programmatically:
public function _prepareLayout(): void
{
$this->setTemplate('Vendor_Module::product/view.phtml');
parent::_prepareLayout();
}
Passing Data to Templates
Method 1: Public Methods
// Block class
public function getProductPrice(): float
{
return $this->_registry->registry('current_product')->getPrice();
}
// Template (.phtml)
$price = $block->getProductPrice();
echo $this->helper('Magento\Framework\Escaper')->escapeHtml($price);
Method 2: setData in Layout XML
<block class="Vendor\Module\Block\Widget"
name="vendor.widget"
template="Vendor_Module::widget.phtml">
<arguments>
<argument name="title" xsi:type="string">Custom Widget</argument>
<argument name="show_header" xsi:type="number">1</argument>
</arguments>
</block>
Access in block:
public function getTitle(): string
{
return $this->getData('title');
}
Method 3: Layout Update in Block
public function _prepareLayout(): void
{
$this->setChild('price_block',
$this->layoutFactory->create()->createBlock(
\Vendor\Module\Block\Product\Price::class
)
);
parent::_prepareLayout();
}
Template Variables
In .phtml templates, $block refers to the current block:
// Access block methods
$block->getProductName();
$block->getProductPrice();
// Access layout
$layout = $block->getLayout();
// Access request
$request = $block->getRequest();
// Access URL builder
$url = $block->getUrl('vendor/module/action', ['id' => 1]);
// Access store manager
$storeId = $block->getStoreManager()->getStore()->getId();
Block Caching
Why Cache Blocks?
Block caching prevents re-rendering the same block content on every page load. If the underlying data hasn't changed, Magento serves the cached HTML.
Cache Key
Each block needs a unique cache key:
public function getCacheKey(): string
{
return 'vendor_module_product_' . $this->getProductId();
}
For complex keys, use the cache key info array:
public function getCacheKeyInfo(): array
{
return [
'VENDOR_MODULE_PRODUCT_VIEW',
$this->getStoreId(),
$this->getProductId(),
$this->getCustomerGroupId(),
$this->isSecure(),
];
}
Magento concatenates these with underscores for the final cache key.
Cache Lifetime
Control how long the cache persists:
public function getCacheLifetime(): ?int
{
return 3600; // 1 hour in seconds
}
// No caching
public function getCacheLifetime(): ?int
{
return null;
}
// Dynamic lifetime based on data
public function getCacheLifetime(): ?int
{
$product = $this->_registry->registry('current_product');
return $product->isSalable() ? 3600 : 300;
}
Cache Tags
Use cache tags for targeted invalidation:
public function getCacheTags(): array
{
return [
'vendor_module_product',
'catalog_product_' . $this->getProductId(),
];
}
Complete Caching Example
namespace Vendor\Module\Block\Product;
use Magento\Framework\View\Element\Template;
class ProductList extends Template
{
public function __construct(
Template\Context $context,
private \Vendor\Module\Model\ResourceModel\Product\CollectionFactory $collectionFactory,
array $data = []
) {
parent::__construct($context, $data);
}
public function getProducts(): array
{
return $this->collectionFactory->create()
->addAttributeToSelect(['name', 'price', 'image'])
->setPageSize(10)
->getItems();
}
public function getCacheKey(): string
{
return 'vendor_product_list_' . $this->getStoreId();
}
public function getCacheLifetime(): ?int
{
return 1800; // 30 minutes
}
public function getCacheTags(): array
{
return ['vendor_product_list'];
}
}
Cache Invalidation
Clear block cache programmatically:
$cacheType = 'block_html';
$this->cacheManager->clean($cacheType);
// Or via CLI
bin/magento cache:clean block_html
Block Registry and Layout Integration
Registry Access
Blocks can access the Magento registry for current page context:
// Current product (on product page)
$product = $this->_registry->registry('current_product');
// Current category (on category page)
$category = $this->_registry->registry('current_category');
// Current CMS page
$cmsPage = $this->_registry->registry('current_cms_page');
// Custom registry values
$value = $this->_registry->registry('my_custom_key');
Layout Methods in Blocks
public function _prepareLayout(): void
{
// Set page title
$this->pageConfig->setTitle(__('My Page Title'));
// Add meta keywords
$this->pageConfig->setKeywords('magento, module, custom');
// Add breadcrumbs
$this->getLayout()->getBlock('breadcrumbs')
->addCrumb('home', ['label' => __('Home'), 'link' => $this->getBaseUrl()])
->addCrumb('category', ['label' => __('Category')]);
// Add custom head content
$this->pageConfig->addRemotePageAsset(
'https://example.com/style.css',
'rel="stylesheet" type="text/css" media="all"'
);
parent::_prepareLayout();
}
Creating Blocks Programmatically
// In a block or controller
$block = $this->layoutFactory->create()->createBlock(
\Vendor\Module\Block\Custom::class,
'unique_block_name'
);
$block->setData('my_value', 'hello');
$html = $block->toHtml();
Child Blocks
// Add child block in _prepareLayout()
$this->setChild('child_block_name',
$this->getLayout()->createBlock(
\Vendor\Module\Block\Child::class
)
);
// Render child block in template
echo $block->getChildBlock('child_block_name')->toHtml();
// Or iterate child blocks
foreach ($block->getChildren() as $child) {
echo $child->toHtml();
}
Sort Order and Aliases
In layout XML:
<block class="Vendor\Module\Block\Custom"
name="custom_block"
alias="custom"
after="-"
before="-"
output="1"/>
name: Unique identifier in layoutalias: Alternative reference nameafter/before: Sort order relative to other blocksoutput: If1, block renders automatically
Quiz
1. What method must a block implement to provide a unique cache key?
2. How do you access a block method in a .phtml template?
3. What does getCacheLifetime() return to disable caching?
Flashcards
Question
What is the base class for most Magento blocks?
Click to reveal answer
Answer
Magento\Framework\View\Element\Template
Question
How do you reference a block in layout XML?
Click to reveal answer
Answer
Use the name attribute: name="vendor.block.name"
Question
What is the difference between getCacheKey() and getCacheKeyInfo()?
Click to reveal answer
Answer
getCacheKeyInfo() returns an array that Magento concatenates into the cache key
Question
How do you access current product in a block?
Click to reveal answer
Answer
$this->_registry->registry('current_product')
Question
What attribute in layout XML makes a block render automatically?
Click to reveal answer
Answer
output="1"
Revision Notes
Key Takeaways
- 1. Blocks extend Template and prepare data for .phtml templates
- 2. Use getCacheKey(), getCacheLifetime(), and getCacheTags() for block caching
- 3. Access data via public methods, layout arguments, or the registry
- 4. Layout XML controls block placement, arguments, and rendering order
- 5. Child blocks allow composition of complex page structures
Interview Tips
- • Explain the block → template rendering flow
- • Know how to implement block caching with proper keys and tags
- • Discuss the registry pattern and when to use it vs DI
- • Be ready to explain layout XML block configuration
Cheat Sheet
Block:
extends Template
$this->_registry->registry('current_product')
$block->getMethodName() in .phtml
Caching:
getCacheKey() → unique identifier
getCacheLifetime() → seconds (null = no cache)
getCacheTags() → array for invalidation
Layout:
<block class="..." name="..." template="..." output="1"/>