Rewrite an Existing Magento 2 Block

This article will help you understand how to rewrite an existing Magento 2 block. In earlier versions of Magento, you had to specify the rewrite within the module’s config.xml configuration file.

In Magento 2, this is done in the module’s di.xml file.

The example below will demonstrate how add a preference in order to override the Magento\Theme\Block\Html\Title class and the getPageHeading() method.

To start with, create a module structure along with the module’s module.xml file.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
    <module name="Siphor_Custom" setup_version="0.0.1" />
</config>

Register the custom module by adding a registration.php file.

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Siphor_Custom',
    __DIR__
);

Run the command to enable the module from within the Magento root directory.

$ /path/to/your/php bin/magento module:enable --clear-static-content Siphor_Custom

After doing this and refreshing your Magento store, you might get encounter the following error.

Please upgrade your database: Run "bin/magento setup:upgrade" from the Magento root directory. 
The following modules are outdated:
Siphor_Custom schema: current version - none, required version - 0.0.1
Siphor_Custom data: current version - none, required version - 0.0.1

To rectify this, run the following command.

$ /path/to/your/php bin/magento setup:upgrade

Now that the custom module has been registered, the module’s di.xml file can be added.

This is where the block override will be specified. The key information resides in the <preference> node.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <preference for="Magento\Theme\Block\Html\Title" type="Siphor\Custom\Block\Html\Title" />
</config>

Finally, add the block class to the location specified in di.xml.

<?php
namespace Siphor\Custom\Block\Html;

class Title extends \Magento\Theme\Block\Html\Title
{

    public function getPageHeading()
    {
        return 'Testing!';
    }

    protected function _toHtml()
    {
        $this->setModuleName($this->extractModuleName('Magento\Theme\Block\Html\Title'));
        return parent::_toHtml();
    }
}

In this specific example, the _toHtml() method is also overridden. This is because the frontend template .phtml file rendered is determined by both the module name of a block and the template attribute of the block.

As the module name specified here is now Siphor_Custom rather than Magento_Theme, the Magento\Theme\Block\Html\Title class should be set within the setModuleName() method of _toHtml().

When reloading the website, you should notice that the page headings have been converted to ‘Testing!’.

Rewrite an Existing Magento 2 Block

Although this is a basic example of how to rewrite an existing Magento 2 block, the same steps apply to more complex Magento 2 blocks that need to be rewritten. When using this method, also check for any existing rewrites if there are any, to avoid rewrite conflicts.

It might be possible to rewrite a Magento 2 block using Plugins, which give you the ability to extend functionality without creating rewrite conflicts. View the post for more information.

Note: This article is based on Magento Community/Open Source version 2.1.