3

Magento 2 has two sets of events that are triggered before the layout is rendered:

  1. in \Magento_Framework_App_View::renderLayout()

    controller_action_layout_render_before
    controller_action_layout_render_before_{$fullActionName}
    
  2. in \Magento\Framework\View\Result\Layout::renderResult()

    layout_render_before
    layout_render_before_{$fullActionName}
    

Since method (2) is only called by method (1), both are always fired. The controller_action part is misleading because there is no controller action involved, the name is probably ported from Magento 1, while the events in (2) are new.

Which one should I use to apply changes to the layout before it is rendered? Does it make any difference?

3

After some debugging because my events were not working, I found the answer myself:

I was wrong, renderResult() is called in another place, \Magento\Framework\App\Http::launch():

    // TODO: Temporary solution until all controllers return ResultInterface (MAGETWO-28359)
    if ($result instanceof ResultInterface) {
        $this->registry->register('use_page_cache_plugin', true, true);
        $result->renderResult($this->_response);
    } elseif ($result instanceof HttpInterface) {
        $this->_response = $result;
    }

So, for all controllers that return a ResultInterface object, Magento\Framework\App\View::renderLayout() is bypassed, and judging by the "TODO" comment this is how it is supposed to work for all controllers in the future.

That means, controller_action_layout_render_before can be seen as deprecated and layout_render_before should be used instead.

The only problem is that there is a bug with the new events that they are triggered AFTER the layout was rendered. This is fixed in develop branch, but not yet in release 2.1.1 (Pull Request on Github)

If the controller action specific events are not needed, a possible alternative is a plugin for \Magento\Framework\View\Result\Layout::renderResult() or even \Magento\Framework\View\LayoutInterface::getOutput() which also has the advantage to have direct access to the layout instance.

Update and Conclusion

A beforeRenderResult() plugin for \Magento\Framework\View\Result\Layout works as intended.

I remember a statement from Magento that plugins are preferred over events now, so controller_action_layout_render_before and layout_render_before can be considered obsolete.

The events with controller action suffix would still be useful, but since they are not working consistently until the bugfix from above is relased, it's safer to use a plugin as well. You can get the full action name from your plugin with:

$subject->getDefaultLayoutHandle()
  • great find! wish i could upvote several times :) – belfort1 Oct 7 '16 at 15:02
1

My answer only refers to how Magento core does it.

The only observer that refers to such changes is declared in Magento/Theme/etc/frontend/events.xml:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="controller_action_layout_render_before">
        <observer name="theme" instance="Magento\Theme\Observer\ApplyThemeCustomizationObserver" />
    </event>
</config>

This observer applies customized static files to the frontend by adding file assets to the page.

So I reckon you should use controller_action_layout_render_before

On top of that, I'm pretty sure using layout_render_before won't work because the layout is rendered before that event is being dispatched:

$this->render($response);

$this->eventManager->dispatch('layout_render_before');

So you can't use that one to change the layout (add handles, add updates) but you can use it to change the output

  • 1
    Right... I just found a GitHub issue with an accepted PR on that: github.com/magento/magento2/pull/3907 - so until this is released, the new events are pretty useless. – Fabian Schmengler Oct 7 '16 at 9:38
  • @fschmengler well actually if they are moved before the render they become duplicate of the old events. Not sure if there's any benefits of having them at all – Raphael at Digital Pianism Oct 7 '16 at 9:40

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.