Rendering in Magento 2
Magento 1.x and Magento 2 rendering is almost identical conceptually. The application will gather all of the modules configuration XML, next it will generate the layout XML which in turn renders to blocks; after this blocks add the templates and render any child blocks within them, finally
toHtml() is called and the it flushes the output.
Rendering our Response.
Magento\Framework\App\View is the main class involved in rendering layout in Magento, this class implements the
The methods which the view interface contain are:
public function loadLayoutUpdates()
public function renderLayout($output = '')
public function getDefaultLayoutHandle()
public function loadLayout($handles = null, $generateBlocks = true, $generateXml = true, $addActionHandles = true)
public function generateLayoutXml()
public function addPageLayoutHandles(array $parameters = , $defaultHandle = null)
public function generateLayoutBlocks()
public function getPage()
public function getLayout()
public function addActionLayoutHandles()
public function setIsLayoutLoaded($value)
public function isLayoutLoaded()
Magento 1.x developers will remember that controllers had the
renderLayout() in the controllers, Magento 2 action controllers don’t have this anymore and the logic has been moved to the View Object.
Magento\Framework\View\Layout is the equivalent to
Mage_Core_Model_Layout class in Magento 1.x, this class is for rendering and generating the layout XML files within Magento.
Magento\Framework\View\Layout extends the
\Magento\Framework\Simplexml\Config class and implements the
I’m not going to list the methods in this interface as there is many, however you should take a look.
In Magento 1.x the controller would load the layout,
loadLayout(), whereas in Magento 2 the controller creates the page object and sends them back to
App::launch(). Only one method is used for rendering and loading the layout in Magento 2
Next, Magento 2 calls
Page::render(), this method calls
$this->pageConfig->publicBuild(); which is a wrapper for
builder object is injected using the DI method (dependency injection) however you can override it using
Magento’s default builder object,
View\Layout\Builder, these classes contain methods which are used in Magento 1.x also:
View\Layout\Builder implements the
BuilderInterface, this only contains a single method:
View\Layout\Builder::build() method looks like this:
Magento 1.x developers should see how old logic is wrapped in a shiny new interface now, cool huh?
Page::renderPage() includes the template set against the object, then includes the file within the
Magento UI Components allow for easily rendering and altering UI elements.
UiComponents refers to the
Magento\Ui module, I recommend looking through the
Component directory in that module.
Some UiComponents are:
- Form Field
The interfaces and meta classes are in
UiComponentInterface interface extends the
UiComponentInterface has the following methods:
public function getName()
public function getComponentName()
public function getConfiguration()
public function render()
public function getComponent($name)
public function getChildComponents()
public function getTemplate()
public function getContext()
public function renderChildComponent($name)
public function setData($key, $value = null)
public function getData($key = '', $index = null)
public function prepare()
public function prepareDataSource(array $dataSource)
public function getDataSourceData()
UiComponents are rendered using
toHtml() much like blocks, check the
Magento\Framework\View\Layout::_renderUiComponent() if you’re interested.
A container renders all of it’s children automatically just like a
core/text_list block. You can’t create an instance of a container because they’re an abstract concept, however you can create an instance of a block, this can be seen in
You can see no instance is created of the container, it’s just rendered along with it’s children; which could be another container. You have the option of adding classes and ID’s your container. You define your containers in XML just like with everything in Magento. A great example of this is in
In Magento 1.x we had a
1column.phtml template, in Magento 2 we have
1column.xml which updates containers from
empty.xml in turn creating a 1 column layout:
I find this pretty exciting as if you got to grips with layout XML in Magento 1.x you’ll know how powerful it is.
Just like in Magento 1.x, the default rendering system is
.phtml. However, good news for front-ends in Magento 2 we can easily use any rendering system.
The Magento 2 fallback system is now done in
You should be able to see we are using a
_templateFileResolution object which is set in the constructor and is an instance of the following class
Magento\Framework\View\Design\FileResolution\Fallback\TemplateFile which in turn extends
This method is using the
resolver object to decide as to which is loaded in using DI, in default case we will have
This class uses the
RulePool object and decides which file to use:
getRule() method is a wrapper around the following function with some conditionals (Not important at the moment):
You can use the DI to add another rule to the
rulePool and change the higher-archy here.
Magento 2 still has Blocks which are fairly unique to Magento. A Block is pretty powerful and provides a set of re-usable methods for you’re templates. Just like in Magento 1.x Blocks have several types:
All of these block types will extend
AbstractBlock which has the
toHtml() method in, this is part of the service contract implemented by the
Containers do not contain any content, they just determine the layout of a page; blocks are the items that have the job of containing content and will be rendered within a container. Blocks can contain blocks, containers can contain blocks, blocks can contain containers and containers can contain containers; don’t get it? Just go watch inception.
In all seriousness if you haven’t worked with blocks in Magento before, you’re probably fairly confused by this explanation.
However blocks are actually a really simple concept. I have taken this image from Alan Kent, i’m sure he won’t mind; here is a diagram of blocks overlaid:
Source (Which I really recommend reading): Alan Kent - MAGENTO 2 CONTAINERS AND BLOCKS
Remember I mentioned the
Page::renderPage() method earlier, this calls the
rootTemplate block, this template is
Eeeeew? Where’s are these magic variables coming from? Calm down, they are set with the
Magento\Framework\View\Result\Page class using the
assign() method, remember we are currently within the output buffering.
This post is mainly aimed at Magento 1.x developers, so I won’t go into any more detail about blocks, however Alan Kent’s post should answer all your questions.
Design Layout XML Schema
If you have come from Magento 1.x, you should be familiar with layout XML. Layout XML is a fundamental part of rendering in Magento, it helps you control the output of you’re templates and what block they should be using.
Layout is pretty much the same as in Magento 1.x, however now we have an exact schema to work with. Also you can add your layout XML within your module
You can also now render attributes within XML:
To add assets your in XML by using the following code:
We now have auto completion in our IDE’s so writing XML should be a lot less painful.
We now have more elements to work with in XML within our containers, like Ui components!:
We also bow have a arguments node where we can specify objects or arrays, if two items in the array share the same key Magento will use the second item, (this is seriously cool!):
Layout handles are the same in Magento 2, however we can now add layout handles in XML
<update handle="new_handle" /> - I can’t really think as to why I would need to use that yet except for keeping my code nicely separated. You can also use
Page::addHandle() to add a layout handle.