2

I have a 3rd party extension installed and I needed to overwrite on block because I could not use events or plugins on it.
The block is added in the layout file like this:

<block class="Vendor\Module\Block" name="some-name" template="path/to/template.phtml" />

Notice that there is no module name specified for the template.

I've overwritten it with this in my di.xml

<preference for="Vendor\Module\Block" type="MyVendor\MyModule\Block" />

now when loading a certain page I get the error path/to/template.phtml does not exist.

I know I can solve this by redeclaring the block in my own layout file and making the template Vendor_Module::path/to/module.phtml and it will work but this is not upgrade proof.
If I upgrade the extension and the template to that specific block changes I will have problems.

My question: Is there an upgrade proof way to overwrite blocks and still keep the templates from the original module?

  • I guess that the only solution in that case Plugin. Using plugin over this block on getTemplate() you can keep the original module template if you will upgrade the module – Amit Bera Mar 15 at 7:58
  • I don't think I need a plugin since I've already overwritten it – Marius Mar 15 at 8:07
  • Since you have your own block you may copy the constructor from Magento\Framework\View\Element\Template and add the "Vendor_Module::" to the configured template path if no vendor/module prefix is set. – HelgeB Mar 15 at 8:10
  • @Marius ,Why you donot change template using gettemplate function at your rewrite class . – Amit Bera Mar 15 at 8:12
  • 1
    This would be the constructor approach - in that way you could set other templates too: protected function _construct() { parent::_construct(); if ($this->hasData('template')) { if (strpos( $this->getData('template') , "::") === false){ $this->setTemplate("Vendor_Module::".$this->getData('template')); } } } – HelgeB Mar 15 at 8:23
2

Based on the comments, I was able solve my problem by adding this method to my block

public function getTemplate()
{
    $template = parent::getTemplate();
    $parts = \Magento\Framework\View\Asset\Repository::extractModule($template);
    if (empty($parts[0])) {
        $template = 'Vendor_Module'.\Magento\Framework\View\Asset\Repository::FILE_ID_SEPARATOR.$template;
    }
    return $template;
}

This way, if the template has a a module specified it will use that template, if not tell magento to load it from the original vendor module.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.