9

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?
18

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).

  • I agree with the principle, however looks like that using preference in di.xml for blocks class type, do not keep some layout configuration. I tried for example to do it for the class \Magento\Catalog\Block\Product\View\Type\Simple, the template default.phtml which was used in our template is ignored. No clue why at the moment – Sylvain Rayé May 24 '17 at 22:54
  • 1
    Jumping in here for more up-to-date information. As of 2.2, extending Block classes is not recommended. Instead, if custom presentation logic is required, a ViewModel should be defined and declared as an argument to the Block in layout.xml. Since ViewModels are built via the Object Manager, you can wire up your own dependency graph without exposing yourself to BC breaking changes in future releases of Magento 2. – John Hall May 4 '18 at 18:36
1

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.

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.