Skip to content
intermediate Phase 34 · Request Lifecycle

PageFactory — Creating CMS Pages

Creating CMS pages, layout handles, page configuration, and dynamic page generation.

45m
0 problems
Topic Progress 0%

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?

Question 1 options

2. How do you add a custom layout handle?

Question 2 options

3. What layout handle is applied to all pages?

Question 3 options

4. How do you set page title?

Question 4 options

Flashcards

Question

What does PageFactory create?

Answer

Page result objects for rendering HTML pages

Question

How do you add a layout handle?

Answer

$page->addHandle('handle_name')

Question

What is the global layout handle?

Answer

*

Question

How do you add CSS to a page?

Answer

$page->getConfig()->addPageAsset('Vendor::css/style.css')

Question

What handle applies to all pages?

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}