Question

I'm starting to see more and more people declaring helpers classes in order to be able to use the following in the template files:

$this->helper('Path/To/Helper/Class')->customMethod();

This kind of code lets people avoid the do not use the object manager directly restriction but I tend to see code that should be block code in those helpers.

So here are my questions:

  • what should one write in the helper classes ?
  • in which cases is it relevant to use helper methods in the templates?
Was it helpful?

Solution

Don't.
This is like using ObjectManager::getInstance()->create() in a template!
Use a custom Block that receives the helper as a constructor dependency instead, and add a proxy method that calls the helper method.

In the template:

$block->customMethod()

In the block:

public function __construct(Path/To/Helper/Class $helperClass, ...other dependencies...)
{
    $this->helper = $helperClass;
    // ...other assignments and call to parent::__construct()
}

public function customMethod()
{
    return $this->helper->customMethod();
}

In OOP principle speak this avoids violating the "Law of Demeter". It encapsulates the business logic in the block instead of the template. As a side effect it also makes the logic more testable as the logic is moved into the block.

Regarding what logic put into the helper classes, I find that in Magento 2 helpers mostly make sense for services, like something that is not a model, but contains reusable code, for example price formatting (which is contained in the core, but I can't think of a better example right now).

OTHER TIPS

I see helpers as global functions inside your module (sorry for the word 'global'), and managers / service contracts as global functions that are allowed to use as well inside as outside your module.

If you follow this principle, you'll see there's minimal use for helpers, I only use them as a configuration wrapper in my modules.

$this->configHelper->get(Config::PATH_TO_XML_PATH);
$this->configHelper->isEnabled();

This kind of stuff. If you have any other functionality that might be practical outside of your module, create a manager instead.

In an ideal world, 3rd party developers who need functionality of other modules should only have to look in the available interfaces for repositories and managers and stuff in the Api-folder.

Since Magento 2.2 ViewModels are the way to go. When use ViewModels you don’t need to extend the block, add constructor with additional dependencies to load parent constructor, etc.

You add a ViewModel by adding following layout xml:

<referenceBlock name="block.name">
    <arguments>
        <argument name="view_model" xsi:type="object">Namespace\Module\ViewModel\MyViewModel</argument>
    </arguments>
</referenceBlock>

ViewModel class:

namespace Namespace\Module\ViewModel;

class MyViewModel implements \Magento\Framework\View\Element\Block\ArgumentInterface
{
    public function customMethod()
    {
      // Implement logic
      // Or call helper

      return $something;
    }
}

After this u can call this method in template file:

$viewModel = $this->getViewModel();
$viewModel->customMethod();
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top