Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Layouts

A layout is an XML file that describes which parts a page consists of and where they stand. The HTML markup itself is not written in a layout: it only arranges blocks. Thanks to that, any module can add a block to another module's page or remove an unneeded one.

Containers and blocks

TermWhat it is
ContainerA place on the page that holds other elements: header, main area, footer
BlockA part of the page with its own template: product name, price, a form

The main area of a page is the content container. This is where you usually add your blocks.

Where a layout lives

Storefront layouts are in the module's view/frontend/layout folder. The file name is built from the three URL parts joined by underscores: for the /hello/index/index page it is hello_index_index.xml. Such a name is called a layout handle.

app/code/Acme/Hello/
├── Controller/Index/Index.php
├── etc/
└── view/
    └── frontend/
        ├── layout/
        │   └── hello_index_index.xml     new file
        └── templates/
            └── greeting.phtml            new file

A layout for your page

<?xml version="1.0"?>
<!-- app/code/Acme/Hello/view/frontend/layout/hello_index_index.xml -->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <block name="hello.greeting" template="Acme_Hello::greeting.phtml"/>
        </referenceContainer>
    </body>
</page>

The layout adds a block named hello.greeting to the content container. The template is written as Module::file — the path is relative to the module's view/frontend/templates folder.

Create the view/frontend/templates/greeting.phtml template with a single line:

<p>Hello from the template!</p>

Run bin/magento cache:clean and open /hello: the text "Hello from the template!" appears in the middle of the shop page. The action from the previous lesson must return a TYPE_PAGE result.

Page layout type

The layout attribute of the page tag picks the number of columns:

<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">

Available values are 1column, 2columns-left, 2columns-right, 3columns.

Changing a core page

To change the product page, create a layout with the same name in your module — catalog_product_view.xml. Magento merges all files of the same name:

<?xml version="1.0"?>
<!-- app/code/Acme/Hello/view/frontend/layout/catalog_product_view.xml -->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="product.info.sku" remove="true"/>
 
        <referenceContainer name="product.info.main">
            <block name="hello.delivery" template="Acme_Hello::greeting.phtml" after="product.info.price"/>
        </referenceContainer>
    </body>
</page>

After bin/magento cache:clean the SKU disappears from every product page, and a block with your template appears below the price. For the module layout to be applied after the catalog layout, module.xml must list Magento_Catalog in the sequence section.

Layout instructions

InstructionWhat it does
referenceContainerRefers to an existing container
referenceBlockRefers to an existing block
blockAdds a new block
moveMoves an element: element, destination, before or after
remove="true"Removes an element from the page

A file named default.xml applies to all storefront pages — it is used to change the header and the footer.

Common mistake

The layout name does not match the URL: the file is called hello_index.xml, or frontName was used instead of the route id. Magento reports no error — the page simply stays empty. The name always has three parts: route id_controller_action, in lower case.

Thanks for reading!

Donate to the site — we work hard for you.