In this blog post, we will see how to add layout file and block to your module
In the previous blog, we created an Excellence_Hello module. Using the same module, we will display “hello world” again but this time using layout/block with a proper page structure.
Step1
In the previous World.php action file, we had simply displayed ‘Hello World’. We will remove that and use magento’s layout system.
The new code for World.php action would be
<?php namespace Excellence\Hello\Controller\Hello; class World extends \Magento\Framework\App\Action\Action { protected $resultPageFactory; public function __construct( \Magento\Framework\App\Action\Context $context, \Magento\Framework\View\Result\PageFactory $resultPageFactory) { $this->resultPageFactory = $resultPageFactory; return parent::__construct($context); } public function execute() { return $this->resultPageFactory->create(); } }
Here we have injected ‘PageFactory’ into the controller’s constructor and which is used further to initialize the layout in execute().
Dependency Injection, is one of the major changes in magento2 and will discuss it in detail later. For now, just use this code directly
Layout
Now we will setup the layout file for our action.
In magento2 all layout files of a module are located at “view/frontend/layout” folder of a module and for each route we need to create a different layout file. In our case the file would be
Excellence/Hello/view/frontend/layout/excellence_hello_world.xml
and content would be
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd"> <referenceContainer name="content"> <block template="content.phtml" class="Excellence\Hello\Block\Main" name="excellence_test"/> </referenceContainer> </page>
more details on how to use layout, template and block, check the theme development series.
magento2 also supports a default.xml layout file, which gets loaded for all action’s of that module
Blocks
Now that we have setup the layout file, next we need to setup block file. As defined in our layout, our block file will be located at
Excellence\Hello\Block\Main
folder.
The contents for block file are
<?php namespace Excellence\Hello\Block; class Main extends \Magento\Framework\View\Element\Template { public function __construct( \Magento\Framework\View\Element\Template\Context $context ) { parent::__construct($context); } protected function _prepareLayout() { } }
this is a simple, empty block with no functions.
Template
Now that our block file is set, next we need to set the template file.
Templates for a module a located in “view/frontend/templates” folder so we need to create the file
Excellence/Hello/view/frontend/templates/content.phtml
We will add the code
<h1><?php echo __('Hello World'); ?></h1>
Now when you open the url /excellence/hello/world you will see “hello world” again but with full page layout (header, footer,etc)
Note: __() is the i18n (multiple language) function for magento2. We should always use this and never directly display a string
Template/Block Passing Data
Passing data from block to template, is used very frequently.
It is very simple to do. Update to block code to
<?php namespace Excellence\Hello\Block; class Main extends \Magento\Framework\View\Element\Template { public function __construct( \Magento\Framework\View\Element\Template\Context $context ) { parent::__construct($context); } protected function _prepareLayout() { $this->setText('Testing'); } }
As you can see we have done
$this->setText()
in our block file.
To access in this in our template file we need to
<?php echo $block->getText(); ?>
There is a big different in how its done in magento1. In magento1 we use ($this) variable in template files, but in magento2 we are using $block
Proper Usage of Block/Template
Block file should contain all the view logic required, it should not contain any kind of html or css. Block file are supposed to have all application view logic.
The template files on the other hand should mainly contain all html scripting. It should contain as little view logic as possible. This is a very important practice to follow.