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