From your Loki Component, you can send notifications to the user via two different mechanisms:
For instance, if you want to show a popup notification in the top of the screen, a global message could be used. If you want messages to be displayed below a certain input field, local messages could be used.
The most common usage is to add messages via the ComponentRepository
class of a component. The following shows how to add global messages:
$this->getGlobalMessageRegistry()->addSuccess('Hello World');`
$this->getGlobalMessageRegistry()->addWarning('Hello World');`
$this->getGlobalMessageRegistry()->addError('Hello World');`
$this->getGlobalMessageRegistry()->addNotice('Hello World');`
These global messages are picked up by the Loki Component GlobalMessages
and rendered server-side. Note however that the messages are actually turned into AlpineJS-based objects, so that the same component also allows sending messages via JavaScript.
The following shows how to add local messages:
$this->getLocalMessageRegistry()->addSuccess($this->component, 'Test success');
$this->getLocalMessageRegistry()->addWarning($this->component, 'Test warning');
$this->getLocalMessageRegistry()->addError($this->component, 'Test error');
$this->getLocalMessageRegistry()->addNotice($this->component, 'Test notice')
Each local message is added to the registry under its own component. The ComponentViewModel
then fetches these messages again (getMessages()
), turns them into JavaScript properties of the Alpine component. Next, the component could add the child-template loki-components.utils.local-messages
to its own PHTML templates to allow rendering of these messages:
<?= $blockRenderer->html('loki-components.utils.local-messages', $block) ?>
Do not try to send messages from your ComponentViewModel
, because you could be adding messages after the local messages have been rendered.
Note that the LocalMessageRegistry
is not part of your own component but it is a separate class. This also explains why you need to pass your own component ($this->component
) as an argument. An added feature here is that you can also add local messages to another component than your own.
If you want to add messages from observers (or other classes), go ahead. Just inject either LocalMessageRegistry
or GlobalMessageRegistry
.
Sometimes, you simply want to trigger a message from JavaScript - for instance, when something fails in JavaScript. For this, the LokiComponentType
object offers a bunch of methods:
this.addGlobalSuccess('Success test');
this.addGlobalNotice('Notice test');
this.addGlobalWarning('Warning test');
this.addGlobalError('Error test');
These methods actually make use of the generic addGlobalMessage()
method, which calls upon the Alpine store LokiMessageStore
which is again linked to an Alpine component that displays these messages. Therefore, you could also call upon the Alpine store directly:
Alpine.store('LokiMessageStore').addMessage('error', 'test3');
Besides global messages, you can also add local messages again:
this.addLocalSuccess('Success test');
this.addLocalNotice('Notice test');
this.addLocalWarning('Warning test');
this.addLocalError('Error test');
These methods actually make use of the generic addLocalMessage()
method, which simply just a new message
object to the internal messages
array of the Alpine component. This means the following also just works:
Alpine.store('LokiComponents').get('example').messages.push({
type: 'warning',
text: 'Warning test',
});
As explained earlier, local messages require the loki-components.utils.local-messages
block to be rendered within the DOM subtree of your component.
You might say why this mechanism was custom-made, instead of re-using the Magento core its message manager. One of the reason is that Loki Components are actually rendered with any change (the AJAX call to modify data is also rendering the block output again), while the core messaging system was designed to temporarily store messages in the session. Furthermore, messages are then rendered client-side by using localStorage
as a mechanism to store messages only for a single HTTP request round. This core mechanism is actually for more complex than the messaging of Loki Components.
When a component value is submitted to the component repository and when a component value is retrieved from the ComponentViewModel::getValue()
method, the value is validated. When the validator is not successfull, a message is added. This message is added by default locally to the component. This therefore requires a loki-components.utils.local-messages
block.
Instead, the message can also be displayed as a global message instead. For this, the component needs to be changed. This can easily be done via a flag dispatch_local_messages
in the XML layout:
<block name="example">
<arguments>
<argument name="dispatch_local_messages" xsi:type="boolean">false</argument>
</arguments>
</block>