Convenient division of front end into separate blocks was implemented back in Magento 1. On the whole, the approach to organizing the display of the front end part was largely taken from the first edition of the platform. How is it implemented in Magento 2?
Here some definitions for a better understanding of the topic of this article:
- Layout – defines the structure of the page using XML. By default — empty.xml, 1column.xml, 2columns-right.xml, 2columns-left.xml, 3columns.xml;
- Container – is used to fill the structure of layouts in the form of more general blocks (header, left, main, footer …);
- Block is a smaller part of the page structure and is used to generate html. These parts are placed directly in containers.
To understand how this works, let’s take a look at the basic Magento_Theme module.
How page structures are defined
First of all, when building a page Magento 2 reads the “page_layout” directory, which contains xml instructions. Let’s consider how “emtpy.xml” works since other layout files use it as a parent one.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd"> <container name="root"> <container name="after.body.start" as="after.body.start" before="-" label="Page Top"/> <container name="page.wrapper" as="page_wrapper" htmlTag="div" htmlClass="page-wrapper"> <container name="global.notices" as="global_notices" before="-"/> <container name="main.content" htmlTag="main" htmlId="maincontent" htmlClass="page-main"> <container name="columns.top" label="Before Main Columns"/> <container name="columns" htmlTag="div" htmlClass="columns"> <container name="main" label="Main Content Container" htmlTag="div" htmlClass="column main"/> </container> </container> <container name="page.bottom.container" as="page_bottom_container" label="Before Page Footer Container" after="main.content" htmlTag="div" htmlClass="page-bottom"/> <container name="before.body.end" as="before_body_end" after="-" label="Page Bottom"/> </container> </container> </layout> |
As you can see, this layout file consists of parts called “container”. This file contains more general page blocks and does not include the container “header”. In fact, a container is the same block as the rest of the page blocks, but with the container type. A block with the container type will automatically output html from the blocks that refer to it.
Blocks such as 1column.xml, 2columns-right.xml, 2columns-left.xml, 3columns.xml have a similar structure and complement empty.xml. For example, 1column.xml adds a header and a footer:
1 2 3 4 5 6 7 8 |
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd"> <update handle="empty"/> <referenceContainer name="page.wrapper"> <container name="header.container" as="header_container" label="Page Header Container" htmlTag="header" htmlClass="page-header" before="main.content"/> <container name="page.top" as="page_top" label="After Page Header" after="header.container"/> <container name="footer-container" as="footer" before="before.body.end" label="Page Footer Container" htmlTag="footer" htmlClass="page-footer"/> </referenceContainer> </layout> |
Similarly, 2columns-left.xml will add a container to display the left column with additional information: sidebar_main, sidebar_additional.
Considering all the above mentioned, you can identify the main containers that are used in Magento 2:
container name = “root”— is used to add basic containers;
container name = “header.container” — displays the top of the page, the so-called “header”;
container name = “main.content” — displays the main content of the page (body);
container name = “footer-container” — is responsible for displaying content in footer.
Of course, these are not all the containers that are used to build a page, but knowing where these files (empty.xml, 1column.xml, 2columns-right.xml, 2columns-left.xml, 3columns.xml, etc.,) are located, you can always look up the names of the required containers.
The role of blocks and templates in the request flow
Now that the page structure from the basic containers is defined, you can add smaller parts of the page. In Magento 2 they are called blocks. Block is a powerful tool for separating application logic and html output. The output of each template is performed by a separate block. In fact, a block is a php class. You can see this more clearly if you look at the connection of the blocks. For example, consider the layout – default.xml file of the Magento_Customer module and the part that is responsible for adding the authorization link.
1 2 3 4 5 6 7 8 |
/** *vendor/magento/module-customer/view/frontend/layout/default.xml */ <referenceBlock name="top.links"> …….. <block class="Magento\Customer\Block\Account\AuthorizationLink" name="authorization-link" template="account/link/authorization.phtml"/> </referenceBlock> |
When rendering a Magento 2 page, it will call the Magento\Customer\Block\Account\AuthorizationLink class, which in its turn calls the account/link/authorization.phtml template indicated in the layout.
Now, from the account/link/authorization.phtml template, you can access all the open methods of the Magento\Customer\Block\Account\AuthorizationLink class using the $block variable.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/** *vendor/magento/module-customer/view/frontend/templates/account/link/authorization.phtml */ $dataPostParam = ''; if ($block->isLoggedIn()) { $dataPostParam = sprintf(" data-post='%s'", $block->getPostParams()); } ?> <li class="authorization-link" data-label="<?php echo $block->escapeHtml(__('or')); ?>"> <a <?php /* @escapeNotVerified */ echo $block->getLinkAttributes(); ?><?php /* @escapeNotVerified */ echo $dataPostParam; ?>> <?php echo $block->escapeHtml($block->getLabel()); ?> </a> </li> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/** *vendor/magento/module-customer/Block/Account/AuthorizationLink.php */ class AuthorizationLink extends \Magento\Framework\View\Element\Html\Link { …………... * Is logged in * * @return bool */ ……………... public function isLoggedIn() { return $this->httpContext->getValue(Context::CONTEXT_AUTH); } } |
Blocks also have various types: for generating lists, forms, tables, etc., but the main purpose of blocks is to separate the business logic and the html output.
When to create a new block or a new template
Whenever you need to change or add the basic functionality of Magento 2, you should use your own blocks or templates, depending on what you need to do. To add new blocks or containers, use the following instructions: referenceBlock, referenceContainer.
The best option is to add new blocks as a separate module, which can be turned on and off without affecting the system as a whole.
Check out BelVG’s quality Magento extensions at our official store.