Table of content

Magento 2 Certified Professional Front End Developer Guide

Section 4: Create and Customize Template Files

4.1. Assign a customized template file using layout XML

How can a customized template file be assigned to a block using layout XML?

Let’s say you want to assign a customized wishlist template.

You need to copy the standard file of the wishlist module.


Paste it to following folder:


Then, you need to create a file:


Another way of changing the template:

And there is also an old method:

There is one more step to make your overriding come into force. You should add a sequence in your module.xml file for the module that contains the changing template file. In this example, your etc/module.xml file will look like this:

It ensures that the Magento_Wishlist module will be downloaded and added to the common template file before your module. If you need to assign a customized template file which displays necessary content, you need to create a new .phtml file in the folder with the theme in the magento_theme module:


With the default content (link with the icon and text):

Then you need to assign the created block in the XML file where you want (for example, you want to add the link with the icon to the header close to the other links):


At the same time, we add the XML file.


We add the following code to the file:

Clear the cache:

php bin/magento cache:flush

On the front, we get the following:


If you need to customize the standard template of the module and display it in the necessary place on the website, you should do the following:

Copy the necessary template file to the folder with the theme by relative path.

For example, the addtocart.phtml template is on the path:


Copy on the path:


Then, in the XML file, we set the template display in the necessary place :

You need to change name and as to the custom ones to make sure they are not the same as name and as of the original block.

Then, we clear the cache:

php bin/magento cache:flush

As a result, you see two identical blocks one of which is located in the place that we need. (For example, standard block output can be removed with the help of <referenceBlock name=" " remove="true"/>):


This way, the block can be displayed anywhere.

How does overriding a template affect upgradability?

When you override the template file with the help of layout XML, you actually violate the fallback path for the template. It does not allow the themes to modify the templates. While upgrading a module, it can happen that new functionality which appears in templates after the upgrade, is not available on the website as the template has been overridden.

What precautions can be taken to ease future upgrades when customizing templates?

If you are a backend developer: use plugin for the block (in this case, it will not allow to use view models), which will turn on the set template only when needed. The best way is to avoid overriding when possible.

4.2. Override a native template file with a customized template file, using the design fallback

How can the design fallback be used to render customized templates?

If you need to use a customized template instead of the standard one, all you need is to copy the necessary phtml file to your theme with the right path. This way you override the standard theme. For example, in order to use customized template of the “Add to the Cart” button for the product:

Copy the file:

<Magento folder>\vendor\magento\module-catalog\view\frontend\templates\product\view\addtocart.phtml


Then, move it to the path:

<Magento folder>\app\design\frontend\BelVG\<theme_name>\Magento_Catalog\templates\product\view\addtocart.phtml


On the front:


How does that influence upgradability?

When upgrading, the template functionality can be interrupted. The reason is that the template which has been overridden, could be upgraded together with the other system aspects which depend on the template. If the overridden template does not upgrade, everything can break down.

How can you determine which template a block renders?

In Magento 2, there are a few ways to find out which template renders.You can search in the Magento files. Usually, the template files are in the XML files of the layout. In the XML file (for example, if you look for the .box-tocart block of the addtocart.phtml template, it is likely to be set in the <Magento_folder>\app\design\frontend\BelVG\<theme_name>\Magento_Catalog\layout\catalog_product_view.xml file). You need to find the block which renders by the template:

In the block, we see template="product/view/addtocart.phtml"

path to the template. In some places, the template file is defined in the PHP class. Then, you need to search for the word $_template in the block’s class.

Defining the template


The easiest way to look at the path to the template is to enable the template path hints. In order to do this, proceed to:

STORES -> Settings -> Configuration


Here, on the tab ADVANCED -> Developer in the “Debug” section, you give the priority “Enabled Template Path Hints for Storefront” value “Yes”.


As a result, on the website, you can see the paths to the templates in red:


Another way to enable the path to the template is via the console command:

bin/magento dev:template-hints:enable

4.3. Describe conventions used in template files

What conventions are used in PHP templates?

  • $this is no longer applicable to the block rendering. No matter which object you use in the template ($ block or $ this), it will always call the method from $block. If you take a look at \Magento\Framework\View\TemplateEngine\Php::__call() you will see:
  • Here you can see that  \Magento\Framework\View\TemplateEngine\Php is just a proxy between the template and $block, so the use of $block is preferable because of the direct call.
  • echo command in PHP should be written using a short tag in the Magento templates. <?= $block->getModuleName() ?> instead <?php echo $block->getModuleName() ?>
  • To make sure that your theme is displayed correctly with any language applicable to store view, check that unique lines of your theme are added in i18n. To get your new line added to the vocabulary and translated, use the __(‘<your_string>’) method when displaying the line in the .phtml template.

    If the line includes a variable, then you should use the following syntax:
  • If you need to use loop, use the foreach > endforeach constructions

Why aren’t the common PHP loop and block constructs used?

Magento templates do not use constructions with { } because curly brackets are more difficult to identify in HTML.

Which common methods are available on the $block variable?

All the common methods from the block context are available in template.

Block context is a block class which is assigned to the template in layout XML file. It is equal to the block type in Magento 1. By default it is \Magento\Framework\View\Element\Template which is equal to Mage_Core_Block_Template in Magento 1.

This block context is assigned to the template as the $block variable during rendering.

Name the common methods available on the $block variable:

getRootDirectory() – Instantiates filesystem directory

getMediaDirectory() – Get media directory

getUrl($route = '', $params = []) – Generate url by route and parameters

getBaseUrl() – Get base url of the application

getChildBlock($alias) – Retrieve child block by name

getChildHtml($alias = '', $useCache = true) – Retrieve child block HTML

getChildChildHtml($alias, $childChildAlias = '', $useCache = true) – Render output of child child element

getChildData($alias, $key = '') – Get a value from child block by specified key

getBlockHtml($name) – Retrieve block html

formatDate($date = null, $format = \IntlDateFormatter::SHORT, $showTime = false, $timezone = null) – Retrieve formatting date

formatTime($time = null, $format = \IntlDateFormatter::SHORT, $showDate = false) – Retrieve formatting time

getModuleName() – Retrieve module name of block

escapeHtml($data, $allowedTags = null) – Escape HTML entities

escapeJs($string) – Escape string for the JavaScript context

escapeHtmlAttr($string, $escapingSingleQuote = true) – Escape a string for the HTML attribute context

escapeCss($string) – Escape string for the CSS context

stripTags($data, $allowableTags = null, $allowHtmlEntries = false) – Wrapper for standard strip_tags() function with extra functionality for html entities

escapeUrl($string) – Escape URL

getVar($name, $module = null) – Get variable value from view configuration

How can a child block be rendered?

Use the  \Magento\Framework\View\Element\AbstractBlock::getChildHtml() method:

Here is the example of use:

Or in the template:

How can all child blocks be rendered?

The same way as you would call a specific child block but without using the name variable:


How can a group of child blocks be rendered?

The block group methods are located in vendor/magento/framework/View/LayoutInterface.php

The main group example in Magento core is located on the product detail page’s tabs (

Their rendering includes getting all their names with the use of getGroupChildNames and then rendering of every block by name in the loop.

4.4. Render values of arguments set via layout XML

How can values set on a block in layout XML be accessed and rendered in a template?

Let’s take a look at the example. For instance, you want to add a class to the product form block using XML.

In order to do it, in the module file (for example,

/app/design/frontend/{vendor_name}/{theme_name}/Magento_Catalog/layout/catalog_product_view.xml), you need do add the following:

In block, we set an argument with the name “custom_class” (or any other), assign a type (type=”string”), then the value – “custom-class”

In order to use this value in the template file you should use one of the following methods:


$cssClass = $block->hasCustomClass() ? ' ' . $block->getCustomClass() : '';


$cssClass = $block- >getData('ustom_class');

Let’s add the variables with different methods of obtaining the value and render them in the class=”” attribute.

As a result, it looks like that:


4.5. Demonstrate ability to escape content rendered and template files

How can dynamic values be rendered securely in HTML, HTML attributes, JavaScript, and in URLs?

To render the values securely, you need to use the block’s built-in methods:

For JavaScript:     $block->escapeJs('value');

For HTML:            $block->escapeHtml('value', $allowedTags);

HTML attributes:    $block->escapeHtmlAttr('value', $escapeSingleQuote);

URLs:                     $block->escapeUrl($url);

All these methods are described in AbstractBlock (Magento\Framework\Escaper)


The unicode symbols are encrypted, for example,⌛ turns into U+231B. This method is used for JS string literal. For inline JavaScript,

(for example, onсlick) you should use escapeHtmlAttr()


It should be your method of escaping data by default for any output. The main point is that the output of all the methods that do not include “Html” should be escaped.


Use it for escaping the output in the HTML attribute, for example:

By default, it also escapes single quotes:

Set the value false on the second variable if you do not need it.


This method is used for URL output. It applies HTML literal by default and additionally deletes javascript:, vbscript: and data:. If you want to deny URLs similar to these among the links provided by a user, you can use the method.

In the releases before Magento 2.1, this function was not enabled and you had to use escapeXssInUrl().


Vlad-Yunusov banner

Tell us about your project

Get in touch with our team. Send us an email at [email protected] or call us 1 650 353 2301

Send request