PageFactory Overview
PageFactory creates page results with layout configuration.
Basic PageFactory usage:
<?php
namespace Vendor\Module\Controller;
use Magento\Framework\App\Action\Action;
use Magento\Framework\View\Result\PageFactory;
class Index extends Action
{
public function __construct(
Context $context,
private PageFactory $pageFactory
) {
parent::__construct($context);
}
public function execute()
{
return $this->pageFactory->create();
}
}
PageFactory vs ResultFactory:
PageFactory: Dedicated page creation, cleaner API
ResultFactory: General result creation, multiple types
// Both equivalent:
return $this->pageFactory->create();
return $this->resultFactory->create(Page::class);
Page with title:
public function execute()
{
$page = $this->pageFactory->create();
$page->getConfig()->getTitle()->set(__('My Custom Page'));
return $page;
}
Page with layout handles:
public function execute()
{
$page = $this->pageFactory->create();
$page->addHandle('vendor_module_custom');
return $page;
}
Layout Handles
Layout handles control which XML layout updates are applied to a page.
Default handles:
* — All pages
default — Default page handle
{route_name} — Route-specific handle
{route_name}_{controller_name} — Controller handle
{route_name}_{controller_name}_{action_name} — Action handle
Adding custom handles:
public function execute()
{
$page = $this->pageFactory->create();
// Add custom handle
$page->addHandle('vendor_module_product_view');
// Add handle with parameters
$page->addHandle('vendor_module_category', [
'category_id' => $categoryId
]);
return $page;
}
Layout XML for handles:
<!-- vendor_module_layout.xml -->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<update handle="vendor_module_custom"/>
<body>
<referenceContainer name="content">
<block class="Vendor\Module\Block\Custom" name="custom_block"
template="Vendor_Module::custom.phtml"/>
</referenceContainer>
</body>
</page>
Conditional handles:
public function execute()
{
$page = $this->pageFactory->create();
if ($this->isSpecialPage()) {
$page->addHandle('vendor_module_special');
}
if ($this->isLoggedIn()) {
$page->addHandle('customer_logged_in');
}
return $page;
}
Page Configuration
Configure page metadata, scripts, and styles.
Page metadata:
public function execute()
{
$page = $this->pageFactory->create();
// Title
$page->getConfig()->getTitle()->set(__('Product Page'));
// Meta description
$page->getConfig()->setMetadata([
'description' => __('Product details page')
]);
// Keywords
$page->getConfig()->setMetadata([
'keywords' => __('product, details, info')
]);
return $page;
}
Adding CSS and JS:
public function execute()
{
$page = $this->pageFactory->create();
// Add CSS
$page->getConfig()->addPageAsset('Vendor_Module::css/custom.css');
// Add JS
$page->getConfig()->addPageAsset('Vendor_Module::js/custom.js');
// Add inline CSS
$page->getConfig()->addPageAsset('Vendor_Module::css/inline.css', [], [
'media' => 'screen'
]);
return $page;
}
Set page layout:
public function execute()
{
$page = $this->pageFactory->create();
// Set layout handle
$page->addHandle('1column'); // or '2columns-left', '3columns'
return $page;
}
Page content blocks:
public function execute()
{
$page = $this->pageFactory->create();
// Get layout
$layout = $page->getLayout();
// Add block to content
$block = $layout->getBlock('content');
$block->setProduct($this->product);
$block->setCategory($this->category);
return $page;
}
Dynamic Page Generation
Generate pages dynamically based on data and configuration.
Product page:
public function execute()
{
$productId = $this->getRequest()->getParam('id');
$product = $this->productFactory->create()->load($productId);
if (!$product->getId()) {
$this->messageManager->addErrorMessage(__('Product not found'));
return $this->_redirect('*/');
}
$page = $this->pageFactory->create();
$page->getConfig()->getTitle()->set($product->getName());
$page->getLayout()->getBlock('content')
->setProduct($product);
return $page;
}
Category page:
public function execute()
{
$categoryId = $this->getRequest()->getParam('id');
$category = $this->categoryFactory->create()->load($categoryId);
$page = $this->pageFactory->create();
$page->addHandle('catalog_category_view');
$page->addHandle('catalog_category_view_type_' . $category->getDisplayMode());
$page->getConfig()->getTitle()->set($category->getName());
return $page;
}
CMS page from database:
public function execute()
{
$identifier = $this->getRequest()->getParam('identifier');
$page = $this->cmsPageFactory->create()->load($identifier, 'identifier');
if (!$page->getId()) {
return $this->_redirect('noroute/index');
}
$resultPage = $this->pageFactory->create();
$resultPage->getConfig()->getTitle()->set($page->getTitle());
return $resultPage;
}
Quiz
1. What is the difference between PageFactory and ResultFactory?
2. How do you add a custom layout handle?
3. What layout handle is applied to all pages?
4. How do you set page title?
Flashcards
Question
What does PageFactory create?
Click to reveal answer
Answer
Page result objects for rendering HTML pages
Question
How do you add a layout handle?
Click to reveal answer
Answer
$page->addHandle('handle_name')
Question
What is the global layout handle?
Click to reveal answer
Answer
*
Question
How do you add CSS to a page?
Click to reveal answer
Answer
$page->getConfig()->addPageAsset('Vendor::css/style.css')
Question
What handle applies to all pages?
Click to reveal answer
Answer
*
Revision Notes
Key Takeaways
- 1. PageFactory creates page results with cleaner API than ResultFactory
- 2. Layout handles control which XML layout updates apply
- 3. Add custom handles via $page->addHandle()
- 4. Page metadata: title, description, keywords
- 5. Add CSS/JS via addPageAsset()
- 6. Dynamic pages load data and configure layout in controller
Interview Tips
- • Explain PageFactory vs ResultFactory
- • Describe layout handle system
- • Know how to create dynamic pages
- • Discuss page configuration options
Cheat Sheet
PageFactory Cheat Sheet
Create page:
$page = $this->pageFactory->create();
Add handle:
$page->addHandle('custom_handle');
$page->addHandle('with_param', ['id' => $id]);
Set title:
$page->getConfig()->setTitle(__('Title'));
Add assets:
$page->getConfig()->addPageAsset('Vendor::css/style.css');
Default handles:
- (all pages)
- default
- {route_name}
- {route}_{controller}
- {route}{controller}{action}