Rendering

  • Templates handle (P)HTML, and some JS
  • Blocks are reusable pieces of functionality tied to templates
  • UI Components are used in JS, but get their data from the backend
  • Layouts pull together the templates for rendering

Rendering Flow

  1. Gather layout config
  2. Generate layout XML
  3. Generate Blocks
  4. Execute output blocks
  5. Include templates
  6. Execute child blocks
  7. Flush output

Routing Flow

  • ResultInterface::render() calls View::loadLayout() calls View::rednerLayout()

    • View is Magento\Framework\App\View which implements Magento\Framework\App\ViewInterface
  • App::launch()

  • Page::renderResult()
  • Page::render()
  • Page::renderPage() (which includes the root template)
  • Response::appendBody()

Public Build

  • View\Page\Config::publicBuild()
    • View\Page\Config::build()
      • View\Layout\Builder::build()
        • loadLayoutUpdates()
          • Magento\Core\Model\Layout\Merge::load()
        • generateLayoutXml()
          • View\Layout::generateXml()
        • loadLayoutBlocks()
          • View\Layout::generateElements()

View Elements

  • UI Components
  • Containers
  • Blocks

UI Components

  • Standalone, reusable elements used on the page
  • Used for grids, forms, minicart etc

  • Several Magento\Ui\Components extend Magento\Ui\Component\AbstractComponent:

  • UiComponentInterface extemds BlockInterface
    • getName()
    • getComponentName()
    • getConfiguration()
    • render()
    • addComponent()
    • getParentName()
    • getRenderContext()
    • getElements()
    • setElements()
    • getConfigBuilder()

Containers

  • Are not backed by a Block class
  • Allows for setting a tag and attributes to an element

Blocks

  • Blocks are placed within containers to decide where they will appear
  • Blocks provide access to data, callable by templates
  • The root template echos a $layoutContent variable
    • This is provided by the Page::render() method from $this->getLayout()->getOutput()

Block Architecture

  • The Template, Text etc Block types extend AbstractBlock, which implements BlockInterface
  • BlockInterface defines only public function toHtml()
  • BlockAbstract implements
    • _prepareLayout() - executed when the block is created. Is often overridden.
    • addChild()
    • _toHtml()
    • _beforeToHtml()
    • _afterToHtml()
    • toHtml() - not recommended to be overridden
  • _prepareLayout() is executed when a Block is created
  • toHtml() should not be overridden; _toHtml() should be used instead

Blocks are rendered as follows:

  • App
  • Page::renderResult()
  • Page::render() gets Layout::getOutput()
  • Page::renderPage() includes the rootTemplate
  • Response::appendBody()

Block Types

  • Magento\Framework\View\Element\
    • Text returns text added with the addText() method
    • Text\ListText contains other children in a sortable list
    • Messages is used for success, info, error banners. Contains a list of messages and can be rendered with a template
    • Redirect is a type of Template, and performs a JavaScript redirect
    • Template includes a .phtml file assigned using either setTemplate() or a template key in the constructor's $data parameter
      • Block::_toHtml() -> Block::fetchView() -> templateEngine::render() -> include $file

Creating Blocks

  • $layout->createBlock()
  • Object Manager
  • DI/Plugins

Block Rendering

  • Layout::getOutput()
  • Block::toHtml()
  • Containers inempty.xml
  • Renders child Block::toHtml()

Templates

  • Contain PHP and HTML code
  • Are contained within a module's view/(area)/templates folder
  • Method calls from templates can only access a block's public functions

Overriding templates

  • In a custom module, create a new template and assign that template to the original block

Template Fallback

  • Block::getTemplateFile()
  • viewFileSystem::getTemplateFileName()
  • View\Design\FileResolution\Fallback\TemplateFile::getFile()
  • View\Design\FileResolution\Fallback\Resolver\Simple::resolve()
  • View\Design\Fallback\RulePool::createRule()
  • (Fallback) View\Design\FileResolution\Fallback\Resolver\Simple::resolveFile()

Cascades as follows:

  • app/design/frontend//templates/
  • app/design/frontend///templates/
  • ///view/frontend/templates/
  • ///view/base/templates/

Layout XML

  • Each layout handle is handled by its own layout file
  • Has different sections:
    • head
    • body
    • html
    • update
  • Located in:

    • Modules' view/(area)/layout folder
    • Themes' Namespace_Module/layout/ folder
    • Themes' layout/ folder

    /page/ @layout - column count html/ attribute/ @name @value head/ css/ @src - [Namespace_Module::]css/style.css or https://xyz.com/style.css script/ @src - [Namespace_Module::]js/script.js link/ @src @ie_condition @defer title/ meta/ @name @content attribute/ @name @value remove/ body/ attribute/ @name @value container/ @name @as @before @after @htmlTag @htmlClass @htmlId @label block/ @class @name @template - template blocks only argument/ @name @xsi:type @translate action/ @method argument/ @name @xsi:type @translate - string types only item/ - array types only @name @xsi:type move/ @element @desination @before @after referenceBlock/ @name @remove referenceContainer @name @remove ui_component/ @name @component /layout/

Directories

  • app/code///view/(area)/layout
  • app/design///view/(area)/layout
  • app/design/*/view/(area)/page_layout
    • empty.xml, 1column.xml, 2columns-left.xml, 2columns-right.xml, 3columns.xml

Inheritance

  • Inheritance is handled by looping over each theme's parent
  • Can be overridden by using (theme)/layout/override
    • This is not best practice
  • Overriding modules' layout files can be done using (module_name)/layout/file_to_override.xml

Layout Handles

  • Starts with default.xml
  • A page-specific one is then loaded
    • These can be catalog_product_view.xml, or more specific like catalog_product_view_id_123.xml
  • Custom handles can be created
    • PHP: Magento\Framework\View\Result\Page::addHandle('custom_handle')
    • XML: <update handle="example_handle" />