how-to-override-template-for-magento-2

How To Master In Magento 2 Override Template Within 5 Minutes

Magento 2 override template can be seen as one of the most popular tasks for Magento 2 platform developers and designers. 

Right! In case you want to update some of your Magento 2 templates but rather to make changes directly to the files, adding extra data, or override Magento templates is available to you.

Even if you are a beginner or professional, you should read this article as we will provide a better understanding of this well-known task.

Come with us right now!

What Is Magento 2 Override Template?

When you start learning a new subject, you need to understand the definition of it thoroughly. In this section, we will give you a detailed concept of the override template for Magento 2.

In case you have already known about this term, let’s skip the following information below to the next instructions.

However, it is so necessary to read this article carefully if you have just begun to make familiar with it.

Don’t hesitate! Let’s become a master in Magento 2 override template by using this article.

override-template-for-magento

>>>Don’t hesitate! Click here to know more about Magento 2 default theme configurable!

In the technological aspect, override is a feature that allows a subclass to provide a specific implementation of the method provided by one of its parent classes.

To make it more understandable,  if the subclass has one or more methods similar to one of its parent classes, then that is the method override.

In the fundamental aspect, sometimes, we need to make modifications to existing templates Instead of making changes directly to finished template files, updating extra data called the category listing page is available as a more advanced method.

override-template-magento-2-bank

>>>Don’t miss this: Useful Magento theme customization tutorial step by step!

For example, the Account class represents a generic bank account. It provides a withdrawal function, which performs the necessary withdrawal process: subtract the amount withdrawn from the account balance.

FeeBasedAccount is a type of bank account that charges a fee for each withdrawal, meaning that besides the necessary withdrawal process, there is an additional function of deducting withdrawal fees from the account balance.

As such, FeeBasedAccount does need the content of the function provided by Account class but still has to override an extra function because such material is not enough to use.

What to expect from Magento 2 override template

  • Customization retained during upgrades

This is an excellent point, as all your data won’t be lost. As a result, you can save a lot of time and avoid setting your module many times.

  • More control over theme files 

Override template for Magento 2 helps you manage your files more accessible and simpler. In the past, it was difficult for you to control all theme files as they are too much and not placed in order.

Condition of The Override Function

override-function-magento

>>>Don’t forget: Top 7 best selling Magento Premium Themes for 2020!

The overriding method requires the parent class, the so-called parent theme, which is specified in the child theme theme.xml declaration file.

For example, the Orange theme by OrangeCo inherits from the Magento Blank theme. The inheritance is declared in app/design/frontend/OrangeCo/orange/theme.xml as follows:

theme xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”urn:magento:framework:Config/etc/theme.xsd”>

<?    <title>Orange</title>

     <parent>Magento/blank</parent>

     <media>

         <preview_image>media/preview.jpg</preview_image>

     </media>

</theme>

Apart from the parent class, the subclass, so-called child theme, must be identical in three parts:

  •  Return data type
  • Method name 
  • Parameter list

The relationship between parent and child classes:

    • A child theme may have the same view configuration, templates, layouts, and static files like its parents class.
    • A child theme is used first, whereas the parent theme is just only indirectly active; its static file, layout, and templates will be used if not overridden by the child’s theme.
    • Any theme can be chosen to display, whether or not it specifies a parent theme in theme.xml.

The rule for the overriding template are:

  • It can only apply the overriding method to methods with access modifiers that are public or protected.
  • It cannot change the access modifier of its overrides (the method that is overridden and the method override must be the same access modifier).
  • It must be used with abstract or virtual keywords.
  • It cannot override a static method or non-virtual method.
  • Cannot use modifiers such as new, static, virtual for override method.
  • Cannot override the constructor.

Magento 2 Override Template Setup

magento-2-override-setup

>>>All reviews and comparisons about Magento 2 Themes. Interested?!

Override template for Magento 2 is such a difficult task even it is one of the most common for developers who want to work one the Magento 2 platform.

In this part, we will show you some useful ways and alternative methods to override the template for Magento 2.

These instructions are based on Mageplaza’s guide. Thanks for their sharing and contribution.

Note for this article:

Terms: 

  • The term “Page layouts”, “Page configurations,” and “Generic layouts” are referred to as “layout files.”
  • Layout files with instructions that override the default or parent theme files are referred to as “overriding layout files.”

Theme file path 

If you want to build a theme, this way is the best solution for you.

More specifically, in Magento 2, any module’s or parent theme’s layout, template, or web can be overridden with ease just by placing it in <theme_dir>/<Vendor>_<Module>/path/to/file.

For instance, for the Magento_Theme module, you can place your template in <theme_dir>/Magento_Theme/templates/html/header.phtml, if you want the template which is located at <theme_dir>/<Vendor>_<Module>/view/html/header.phtml to be overrided.

In various cases, you will not be able to specify which module the template belongs to as several block definitions in Magento 2 do not have the Vendor_Module prefix. With these cases, the module with the template belongs to will be defined by the block’s class attribute.

Here is an example, if you want to find a block definition in the Magento_Checkout module, your template would be placed inside the Magento_Checkout module directory that is inside your theme.

Layout Block Agrument

If you want to build a module, this layout method is suitable for you. 

In order to use layout XML to override a template, you will only need to override the template argument of the block. Let’s take the template Magento_Wishlist/view/frontend/templates/view.phtml as an example, for the view.phtml to be overridden with your own template, a new layout file have to be created firstly: <Vendor>_<Module>/view/frontend/layout/wishlist_index_index.xml.

There are two methods that could be applied to override a layout block argument.

New method

<?<?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.wishlist">

            <arguments>

                <argument name="template" xsi:type="string">Vendor_Module::view.phtml</argument>

            </arguments>

        </referenceBlock>

    </body>

</page>

Old deprecated method

<?<?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.wishlist">

            <action method="setTemplate">

                <argument name="template" xsi:type="string">Vendor_Module::view.phtml</argument>

            </action>

        </referenceBlock>

    </body>

</page>

Although it is said that the new method is more appropriate than the old one to override a template with layout xml, there are some cases where it is not working. In these situations, the old method can be used as a temporary one to address the problem.

Next, you must place the new custom template that you have just created in the location where you specified in your layout file. Here, the location is <Vendor>_<Module>/view/frontend/templates/view.phtml.

As the path of the template in a module matches the way you have set in your template attribute, it does not matter. Here, I would want to place the module in the same path you found in its original module, starting from the templates directory of the module. But at the same time, I want to add a directory for the template’s module name you are overriding.

For instance, in your module, a wishlist template is put in <Vendor>_<Module>/view/frontend/templates/wishlist/view.phtml. If the template is catalog template it would be put in <Vendor>_<Module>/view/frontend/template/catalog/view.phtml.

However, to make your override takes effect, the is one extra step that you need to complete which is adding a sequence to your module.xml file for the module which contains the layout file you are modifying.

In this example, here is how your etc/module.xml file will look like: module.xml

<?<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">

    <module name="Vendor_Module" setup_version="100.0.0">

        <sequence>

            <module name="Magento_Wishlist"/>

        </sequence>

    </module>

</config>

This step would help make sure that the module Magento_Wishlist be loaded and added to the merged layout file before your module. This is very important as it ensures the layout override of your module will be parsed after the layout XML has been parsed. If not, your layout override will not be applied as it could be referencing something that doesn’t exist yet.

Class preference

There are some block definitions in which a template attribute is included, but a name attribute is not. These block definitions cannot be overridden from layout XML using the above methods. 

However, you can still override the template by utilizing the class preference method if the template attribute of the block does not contain the prefix Vendor_Module.

To make it easier, you can follow this example cart/item/default.phtml template in Magento/Checkout/view/frontend/layout/checkout_cart_item_renderers.xml.

<?<block class="Magento\Checkout\Block\Cart\Item\Renderer" as="virtual" template="cart/item/default.phtml">

As the scope for the template path is set by the class attribute on the block, a prefix Vendor_Module seems unnecessary if the template and the block’s class are in the same module. In other words, to change the module scope of the template, you only need to replace the class of the block with a class preference in your di.xml file:

<?<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <preference for="Magento\Checkout\Block\Cart\Item\Renderer" type="Vendor\Module\Block\Checkout\Cart\Item\Renderer" />

</config>

Although you don’t actually need to do any customization with the block, you still have to ensure that the block actually exists. In order to ensure this, you just need to create a skeleton block.

<?<?php

/**

 * This block serves as a skeleton class to change the scope of a block definition. 

 * The template attribute on the block will now default to this module rather than the 

 * core module on the original block definition.

 */

namespace Vendor\Module\Block\Checkout\Cart\Item;

class Renderer extends \Magento\Checkout\Block\Cart\Item\Renderer {}

Then, to finish overriding the template, you only need to add your template just like when you do a normal template override from the layout.

Plugin

In the example below, you will use a plugin to override Magento_Catalog:: category/products.phtml with your template.

You can see how the original block definition for the category view template here:

<?<block class="Magento\Catalog\Block\Category\View" name="category.products" template="Magento_Catalog::category/products.phtml">

The plugin will have to look into the class Magento\Catalog\Block\Category\View. The template will be retrieved and turned into HTML using the to Html() method. To override that template, you need to change the $_template variable to your own template. Luckily, a method to do that has already been created in the Template class. With this understanding, your plugin and di.xml files can be created.

di.xml

<?<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <type name="Magento\Catalog\Block\Category\View">

        <plugin name="module_catalog_category_view_override_template" type="Vendor\Module\Plugin\Catalog\Block\Category\View" />

    </type>

</config>

View.php

<?<?php

namespace Vendor\Module\Plugin\Catalog\Block\Category;

class View

{

    public function beforeToHtml(\Magento\Catalog\Block\Category\View $subject)

    {

        if ($template === 'Magento_Catalog::category/products.phtml') {

            $subject->setTemplate('Vendor_>Module::catalog/category/products.phtml');

        }

    }

}

Finally, to finish the template override process, you need to place your template in the appropriate location, which is <Vendor>/<Module>/view/frontend/templates/catalog/category/products.phtml in the module.

Remember that you should only use this method if the block does not have any name and if it has a Vendor_Module prefix and/or has a class that could handle multiple templates.

alternative-methods

Alternative methods

Overriding a template is not always a perfect option for you when modifying something on a page. On various occasions, it would be better for you if you choose an alternative.

The layout structure 

The only thing which is required to a template is an addition to the template’s beginning and end. In such cases, if the block defining the Magento 2 override template inside a container, you just need to create your template file and then locate it before or after the template you want to override. 

The characteristic which you could use to discriminate between blocks and containers is that the blocks’ children have to be explicitly called to be rendered. In contrast, the containers’ children render all of their children blocks and containers. Your new markup is required to be added to the wishlist page, which would create your layout/wishlist_index_index.xml file, just like this:

<?<?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>

        <referenceContainer name="content">

            <block class="Magento\Framework\View\Element\Template" name="some.block" template="Vendor_Module::some-template.phtml" after="customer.wishlist"/>

        </referenceContainer>

    </body>

</page>

Remove an element with JS or CSS

Although this method is not highly recommended, in some cases where you want to avoid removing an element by overriding a template, you can remove that element using JS or CSS. But you have to be careful as if you use this too frequently, large chunks of HTML will be loaded without being displayed to the user. As a result, page load times will be increased leading to messy and hard-to-maintain HTML and CSS. So only use this method when there is no way.

Replace a jQurey widget

Firstly, you need to create JS files in your theme or module:

  • In your theme: <Vendor>/<Theme>/web/js/customAccordion.js
  • In your module: <Vendor>/<Module>/view/frontend/web/js/customAccordion.js

For example,  customAccordion.js

<?define([

  'jquery',

  'jquery/ui',

  'mage/accordion'

], function($){

  $.widget('Vendor_Module.customAccordion', $.mage.accordion, {

      _create: function() {

          // custom code here

      }

  });

  return $.Vendor_Module.customAccordion;

});

The following step is creating a mapping for your customAccodion widget:

  • In your theme: <Vendor>/<Theme>/requirejs-config.js
  • In your module: <Vendor>/<Module>/view/frontend/requirejs-config.js

For instance, requirejs-config.js

<?var config = {

    map: {

        '*': {

            'accordion': 'Vendor_Module/js/customAccordion'

        }

    }

};

After finishing the above steps, your custom accordion will be loaded in any places where you include or initialize accordion.

Add a translation to change a line of text 

In Magento 2, there is an extremely simple technique to override strings of text. The technique is adding an adaptation to your theme or module which matches the text line you want to change after replacing it with any string you set. This is not the best practice approach but in various situations, it is worthy. The reason is that instead of having to override a considerable number of templates, you only need to change a simple text. However, you should be careful in case the string that you are translating is used in different locations.

Possible Mistake Warned   

override-template-warning

Although the override layouts mechanism provides flexible customization, it can add logically irrelevant changes.

Hence, you should not make one of these changes:

  • Changing block name or alias

It would help if you did not change the name of a block, and neither should the alias of a block remaining in the same parent element.

  • Changing handle inheritance. 

Also, you should not change the page type of parent handle.

Final Thoughts

There are so many problems surrounding the Magento 2 override template. However, we have given you relatively information on it and tried our best to explain it to you in an understandable way. We hope that you will find this article interesting and useful.

Read carefully and try to modify by yourself! Figure out which problems you will encounter, or will it be successful? Comment down below for your questions and experiences, eventually.

We will update right after and give you full support.

About Daniel M.

I'm an experienced backend web developer who skilled in Magento, Github, and PHP at Lancaster, Pennsylvania. I'm more than welcome to have you reading my post.
Previous Getting Magento Theme For Store Isn’t A Big Deal
Next 5 Magento 2 Ecommerce Theme That You Cannot Ignore

Check Also

ebay-magento-themes

5 Magento 2 eBay Theme You Should Never Miss!

If you are pursuing the dream, which is to construct a popular marketplace on your …

Leave a Reply

Your email address will not be published. Required fields are marked *