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?

10
  • 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
    Commented Mar 15, 2019 at 7:58
  • I don't think I need a plugin since I've already overwritten it
    – Marius
    Commented Mar 15, 2019 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
    Commented Mar 15, 2019 at 8:10
  • @Marius ,Why you donot change template using gettemplate function at your rewrite class .
    – Amit Bera
    Commented Mar 15, 2019 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
    Commented Mar 15, 2019 at 8:23

1 Answer 1

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 and acknowledge you have read our privacy policy.

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