Displaying Complex Error Messages in Magento 2




When an end user has taken an action in any application it's a good idea to provide the user feedback on that action. So for example if the save product button has been clicked in Magento 2 you would expect to see something like this:

Success: Product Saved

If you are writing custom code for Magento it is fairly straight forward to add your own messages to be displayed to the user. Usually you would do this in your own controller code - the context object provides you with access to the \Magento\Framework\Message\ManagerInterface via $context->getMessageManager() as the framework provided means to do so.

Out of the box the following messages can be used:

$this->messageManager->addSuccessMessage(__('All good'));
$this->messageManager->addNoticeMessage(__('Something you should be aware of is ....'));
$this->messageManager->addWarningMessage(__('This is not so good....'));
$this->messageManager->addErrorMessage(__('This is bad'));

which will then render to the user as: All 4 different message types

This is usually all you need in user interaction.

However sometimes you need that little bit more from those messages, for example you might want to include an URL directly in the message itself. Your first inclination probably looks similar to mine and you end up doing:

$this->messageManager->addNoticeMessage(__('Before we can start please configure something <a href="https://example.com">here</a>'));

but we soon find out that all output gets automatically escaped: It's all escaped

Luckily for us there is an inbuilt solution for us to use custom messages. In the \Magento\Framework\Message\ManagerInterface there is an extra set of methods which all include Complex in their name:

/* @see \Magento\Framework\Message\ManagerInterface */
public function addComplexSuccessMessage($identifier, array $data = [], $group = null);
public function addComplexErrorMessage($identifier, array $data = [], $group = null);
public function addComplexWarningMessage($identifier, array $data = [], $group = null);
public function addComplexNoticeMessage($identifier, array $data = [], $group = null);

To make use of them we first need to set up our identifier via some di.xml instructions:

<!-- etc/adminhtml/di.xml-->
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\View\Element\Message\MessageConfigurationsPool">
        <arguments>
            <argument name="configurationsMap" xsi:type="array">
                <item name="foomanExample" xsi:type="array">
                    <item name="renderer" xsi:type="const">\Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE</item>
                    <item name="data" xsi:type="array">
                        <item name="template" xsi:type="string">Fooman_Example::messages/foomanExample.phtml</item>
                    </item>
                </item>
            </argument>
        </arguments>
    </type>
</config>

The template file could then look like this

/* view/adminhtml/templates/messages/foomanExample.phtml */
<a href="<?php echo $block->escapeUrl($block->getData('url'))?>"><?php echo $block->escapeHtml(__('click here first')) ?></a>

and last but not least we need to invoke this message and pass in the url information as part of the data array:

$this->messageManager->addComplexNoticeMessage(
    'foomanExample',
    [
        'url' => $this->_helper->getUrl('to/our/route')
    ]
    );

And we have our intended end result: Complex Error Message with custom HTML

As a quick reminder do not output user input without properly sanitizing the input and escaping the output. The various $block->escapeX methods like $block->escapeHtml() and $block->escapeUrl() are your friends.

Kristof Ringleff

Kristof Ringleff

Founder and Lead Developer at Fooman

Join the Fooman Community

We send our popular Fooman Developer Monthly email with Magento news, articles & developer tips, as well as occasional Fooman extension updates.