This article is dedicated to a very important aspect from Backend Certification – How to use blocks in Magento 2, which is the part of one large topic 3 “Customizing the Magento UI”. Today we will consider the following questions:
What is block architecture and how is it used in development?
What are the stages in lifecycle of a block?
How are blocks rendered and cached?
What is block architecture and how is it used in development
What is the typical block’s role?
Separation block-template allows you to separate business logic from design..Blocks are usually (but not always) connected to PHTML template files. Blocks can be thought of as a data container for a template, which represents a piece of the HTML on the page. In layouts XML, you can manage blocks on the page and add new ones, set templates to move and delete.
Which objects are accessible from the block?
All block extends \Magento\Framework\View\Element\Template, so by default blocks are injected with a \Magento\Framework\View\ Element\Template\Context object and support getters and setters for returning and storage any objects or data. This object contains a number of other objects that are loaded into the instance:
- $this->validator: \Magento\Framework\View\Element\Template\File\Validator
- $this->resolver: \Magento\Framework\View\Element\Template\File\Resolver
- $this->_filesystem: \Magento\Framework\Filesystem
- $this->templateEnginePool: \Magento\Framework\View\TemplateEnginePool
- $this->_storeManager: \Magento\Store\Model\StoreManagerInterface
- $this->_appState: \Magento\Framework\App\State
- $this->pageConfig: \Magento\Framework\View\Page\Config
What are the stages in lifecycle of a block?
There are two phases of the block life cycle: generating blocks and rendering blocks. Blocks are instantiated at the moment the layout is created. They are not executed at that time, just instantiated. Also during this phase, the structure is built, the children of blocks are set, and for each block, the prepareLayout() method is called.
However, nothing is rendered, as that happens in the later rendering phase.
Generating phase:
- Magento\Framework\View\Page\Config::publicBuild()
- Magento\Framework\View\Page\Config::build()
- Magento\Framework\View\Layout\Builder::build()
- Magento\Framework\View\Layout\Builder::generateLayoutBlocks()
- Magento\Framework\View\Layout::generateElements()
- Magento\Framework\View\Layout\GeneratorPool::process()
GeneratePool goes through all generators and generate all scheduled elements. It has generators with the following elements:
Magento\Framework\View\Page\Config\Generator\Head
Magento\Framework\View\Page\Config\Generator\Body
Magento\Framework\View\Layout\Generator\Block
Magento\Framework\View\Layout\Generator\Container
Magento\Framework\View\Layout\Generator\UiComponent
Rendering phase:
- Magento\Framework\View\Result/Page::render()
- Magento\Framework\View\Layout::getOutput()
At this moment, we already have all the layout xml for the page generated, and all block classes are created.
- Magento\Framework\View\Layout::renderElement()
- Magento\Framework\View\Layout::renderNonCachedElement()
In this method we check type of rendered elements. It creates them and returns html using toHtml() method. This method is not recommended to override. If you want to change block rendering override _toHtml() method.
In what cases would you put your code in the _prepareLayout(), _beforeToHtml(), and _toHtml() methods?
_prepareLayout() – most often used for:
- adding child’s Magento\Eav\Block\Adminhtml\Attribute\Edit\Options\AbstractOptions::_prepareLayout()
- adding tabs on backend Magento\Backend\Block\System\Design\Edit\Tabs::_prepareLayout()
- set title Magento\Wishlist\Block\Customer\Sharing::_prepareLayout()
- adding pager, breadcrumbs and so on Magento\Sales\Block\Order\History::_prepareLayout()
- set renderer Magento\Catalog\Block\Adminhtml\Form::_prepareLayout()
_beforeToHtml()
- data preparing Magento\Catalog\Block\Product\ProductList\Related::_beforeToHtml()
- assign values Magento\Backend\Block\Widget\Form\Element::_beforeToHtml()
- adding child’s Magento\Shipping\Block\Adminhtml\Create\Items::_beforeToHtml()
_toHtml()
Using this method, you can manipulate the rendering of the block, complement the condition, make wrappers for html, change the template for the block etc. Magento\GroupedProduct\Block\Order\Email\Items\Order\Grouped::_toHtml() , Magento\Sales\Block\Reorder\Sidebar::_toHtml()
How would you use events fired in the abstract block?
view_block_abstract_to_html_before – use for editing params:
- templates
- caches
- grids
view_block_abstract_to_html_after – use for html manipulation – editing,add conditions, wrappers.
How are blocks rendered and cached?
The most important method for rendering a block is Magento\Framework\View\Element\AbstractBlock::toHtml(). He first run _loadCache() , if the cache is missing then it run _beforeToHtml() after the block is rendered by the method_toHtml() after which the cache is saved _saveCache($html) and run _afterToHtml($html).
Method _loadCache() uses cache_key return by getCacheKey() and _saveCache($html) – cache_tags obtained by the method getCacheTags(). Cache_key each block is added up like BLOCK_$cache_key , if this property not defined – BLOCK_sha1($name_in_layout). Cache_tags is array and consists of a property $cache_tags, if it defined in block and if block instanceof Magento\Framework\DataObject\IdentityInterface values returned by the method getIdentities() are added to the array. We can manage $cache_lifetime variable. Value will be in seconds, if you want to disable cache you can set value to 0 or not set the value because all blocks are non-cacheable by default.
What are different types of blocks used for?
- Magento\Framework\View\Element\AbstractBlock – parent block for all custom blocks;
- Magento\Framework\View\Element\Template – block with template;
- Magento\Framework\View\Element\Text – just rendering text;
- Magento\Framework\View\Element\FormKey – return hidden input with form key;
- Magento\Framework\View\Element\Messages – rendering notification message by type.
When would you use non-template block types?
When we use simple renderers. When block content is dynamic generated or stored in a database or in containers. For example, if you want form_key in template, you can insert block Magento\Framework\View\Element\FormKey.
In what situation should you use a template block or other block types?
When we use complicate renderers. When we want to customize themes or add new blocks. А prime example is a breadcrumb block Magento\Catalog\Block\Breadcrumbs. If you want to customize breadcrumbs, you can set the template in layout.
This is all to the topic of use of blocks in Magento 2. If you have any questions left or comments, please leave them down below.
Yes, usually they can. However, it depends on a specific template as not all of them can be used with different block instances. The block should provide data used by the template.
Please let me if multiple block instances can use same template?
Ilya
thank you!
I am happy you find it useful!
Thanks! I looked for this information for a long time!
Thanks for your kind words! We do our best to make our blog as comprehensive and possible and are very glad to receive such positive feedback.
Your blogs are awesome. Detailed information. I am feeling like you have opened a machine and put all the parts on the desk with information.