$this deprecated in template logic. What's the alternative?
-
04-03-2021 - |
题
In this https://github.com/magento/magento2/blob/2.3/app/code/Magento/Contact/view/frontend/templates/form.phtml you see something like this
$this->helper('Magento\Contact\Helper\Data')->getUserEmail())
In code quality checks I see $this in templates is now deprecated
What's the recommended approach?
解决方案
I would say that either extending the block or creating a view model that injects the helper, then exposes proxy methods for the data you want to access would be the correct way to do it.
Using helpers directly in template files is generally frowned upon since you are introducing business logic into the template. This just seems like old ported code from M1, that will be refactored into the new design patterns at some point in the future.
But if you really wanted a function that behaved the same way, you could reimplement it into your block since all the helper
function does is load the class through object manager, you can find the implementation here https://github.com/magento/magento2/blob/2.3-develop/lib/internal/Magento/Framework/View/TemplateEngine/Php.php#L120
其他提示
This breaks down into 3 simple steps.
I assume that you are reffering to the contactForm block in the contact_index_index.xml
1) In one of your modules or designs create a contact_index_index.xml in your layout folder
For module
Vendor/Module/view/frontend/layout
Remeber about setting sequence in module.xml for Customer_Contact
For design
Vednor/Theme/Magento_Contact/layout
contact_index_index.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="contactForm" template="Magento_Contact::form.phtml">
<arguments>
<argument name="view_model" xsi:type="object">Vendor\Module\ViewModel\Contact</argument>
</arguments>
</block>
</body>
</page>
2) Create your ViewModel -> Vendor\Module\ViewModel\Contact.php
Contact.php
<?php declare(strict_types=1);
namespace Vendor\Module\ViewModel;
use Magento\Framework\View\Element\Block\ArgumentInterface;
use Magento\Contact\Helper\Data as ContactHelperData;
class Contact implements ArgumentInterface {
/** @var ContactHelperData */
private $contactHelperData;
/** @param ContactHelperData */
public function __construct(ContactHelperData $contactHelperData)
{
$this->contactHelperData = $contactHelperData;
}
/** @return ContactHelperData */
public function getContactHelperData()
{
return $this->contactHelperData;
}
}
3) Use the view_model in your template.
Extend old template. Seems you already did it. Do it in anyway you want I will post an example for theme.
Create the file in
Vendor\Theme\Magento_Contact\templates\form.phtml
now in your form.phtml
/** @var Vendor\Module\ViewModel\Contact $viewModel */
$viewModel = $block->getData('view_model');
/** @var Magento\Contact\Helper\Data $viewModel */
$helper = $viewModel->getContactHelperData();
Bang, that's all :)
Now you can use the helper within the block without worring about the explosion after near future updates :)
Ofc do the text formatting, it's getting late I could made some typos :)
I quite like the original solution
To elaborate in theory
namespace Xigen\Demo\Block;
class Test extends \Magento\Framework\View\Element\Template
{
/**
* Constructor
* @param \Magento\Framework\View\Element\Template\Context $context
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Framework\ObjectManagerInterface $helperFactory,
array $data = []
) {
$this->_helperFactory = $helperFactory;
parent::__construct($context, $data);
}
/**
* Get helper singleton
* @param string $className
* @return \Magento\Framework\App\Helper\AbstractHelper
* @throws \LogicException
*/
public function helper($className)
{
$helper = $this->_helperFactory->get($className);
if (false === $helper instanceof \Magento\Framework\App\Helper\AbstractHelper) {
throw new \LogicException($className . ' doesn\'t extends Magento\Framework\App\Helper\AbstractHelper');
}
return $helper;
}
}
Then in template phtml should be as easy as:
$block->helper(\Magento\Contact\Helper\Data::class)->getUserEmail()