Magento Development 05: Layout and Templates
Now let’s come back to frontend development. Earlier we created a controller where I wrote die statement to show you that the controller is working. But in the real world we have to show html content.
To show html content we use .phtml files. These .phtml files are called template files. To map the controller with .phtml files we use layout files. The layout files are of .xml type. As all of these are related to viewing the page. So it makes sense to put them in a different folder, which is called view folder.
First we need to modify the controller file, Controller/Manage/Add.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php namespace Webkul\BlogManager\Controller\Manage; use Magento\Customer\Controller\AbstractAccount; use Magento\Framework\App\Action\Context; use Magento\Framework\View\Result\PageFactory; class Add extends AbstractAccount { public function __construct( Context $context, PageFactory $resultPageFactory ) { $this->resultPageFactory = $resultPageFactory; parent::__construct($context); } public function execute() { $resultPage = $this->resultPageFactory->create(); $resultPage->getConfig()->getTitle()->set(__('Add Blog')); $layout = $resultPage->getLayout(); return $resultPage; } } |
Here we are using \Magento\Framework\View\Result\PageFactory class to initialize the layout. With this we can configure the page, here we have set the Title of the page. And after calling the getLayout() method to process the layout file, we have returned the result page.
Layout
Now if you notice we have not explicitly mentioned the layout file name in the controller. So magento will look for layout file with name routerId_controllerName_actionName.xml . If we want then we can explicitly give like,
$resultPage->addHandle('some_other_layout'); |
For the layout file we need to create view/frontend/layout folder under the module directory. In the layout folder we need to create layout file with name blogmanager_manage_add.xml . If you remembered we used blogmanager as our router id. It’s common practice to use routerId as same as frontName because then layout file name will be similar to the url.
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="content"> <block class="Magento\Framework\View\Element\Template" name="blogmanager.blog.add" template="Webkul_BlogManager::add.phtml" /> </referenceContainer> </body> </page> |
As you can see in the page tag we have used layout attribute with value 1column. Magento supports different types of layout such as,
i) 1coumn
ii) 2columns-left
iii) 2columns-right
iv) 3columns
The body node refers that we are modifying contents within the body tag of the html. The page layout in magento is made out of multiple containers. And the container can have nested containers. The inner most containers have blocks in them and each block can have child blocks.
For simplicity you can think of header, footer, main content as individual containers. However the magento’s layout structure is much more complex, which help us to modify any component. For 2columns-left layout the main content will have two sub containers, one for content another on the left side as sidebar container.
With the referenceContainer tag we can target any container, here we are targeting the main container whose name is content. You can find more container and block names in vendor/magento/module-theme/view/frontend/layout/default.xml file.
Inside the container we are calling our pthml file with block tag. Here we are using default template block class Magento\Framework\View\Element\Template but we can create our own block class if we have to pass some data into the phtml. We will see more about Block class in the next blog. The block tag have name attribute, we can use any sensible name here to identify that block.
Templates
The interesting part in the block tag is template=”Webkul_BlogManager::add.phtml”, this represents the path of the template file. The first part of :: is the module name and second part is the path in reference to the view/frontend/templates folder. As in the path we have given the phtml file name so we can directly create add.phtml file under view/frontend/templates folder.
<div class="blog-container"> <form class="blog-form"> Title: <input type="text" name="title"/> Content: <textarea name="content"></textarea> <button type="submit">Submit</button> </form> </div> |
After writing all of these code we have to run the di compile command. And now if you browse the url you will see the page,
Please try out different layout types on your own.
If you make some changes in the template file and can not find it when reloading the page then please flush the cache.
php bin/magento cache:flush |
We are aiming to create blog portal where customers can write blogs. So it make much more sense that the page should appear like other customer account pages and instead of manually entering the url we should have a menu in the customer navigation.
To add the customer navigation menu we will follow “Magento2 – Add New Link in My Account Navigation Panel” blog. We have to create customer_account.xml file under view/frontend/layout folder. Magento already have this xml file we are just appending our code into it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="customer_account_navigation"> <block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-blog-add" after="-" > <arguments> <argument name="label" xsi:type="string" translate="true">Add Blog</argument> <argument name="path" xsi:type="string">blog/manage/add</argument> </arguments> </block> </referenceBlock> </body> </page> |
Now let’s modify the blogmanager_manage_add.xml file to match the customer account pages structure.
1 2 3 4 5 6 7 8 9 10 |
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <update handle="customer_account"/> <body> <referenceContainer name="content"> <block class="Magento\Framework\View\Element\Template" name="blogmanager.blog.add" template="Webkul_BlogManager::add.phtml" /> </referenceContainer> </body> </page> |
Here you can see that we have removed the layout type and added <update handle=”customer_account”/> tag. Basically it says that copy everything from the customer_account.xml, so it will copy all the structure from customer_account.xml which acts as a base for every customer account related page.
Now when we di compile and reload we will see something like,
Folder structure till now,
PS. Please run the di compile command if you create a new file, or modify in any .xml file or make changes in constructor of a class. Sometimes running di compile might not have any affect then we should explicitly remove the generated/code folder by running rm -rf generated/code from Magento root directory.
Next Blog -> Coming Soon.
Previous Blog -> Magento Development 04: Model, Resource Model and Collection
. . .
Back to Top
Advertising by Adpathway