Everything a developer changes on a Core dna site lives in its theme repository. This guide covers the repository and its build, printing records in templates, stylesheets and client-side code, and the parts of a site around the main content.
L1–L2
Unit 05 · Around the main content
Messages after a redirect
Around the main contentPage 30 of 35Updated
How the platform carries a message such as "Saved" across a redirect, the five message types, how to render them in Smarty and Twig, and which page shows a queued message.
Who this is for. Developers writing the site chrome that shows confirmations and errors after a form, a sign-in or a payment. After this page you can render every message type in both engines and plan a flow so the message appears on the page you intend.
How a message is queued
Messages are queued by controllers, not by templates; a template only reads them. The platform's Messages service offers two lifetimes:
Method
Lifetime
addMessage()
Shown in the current response only
addRedirectMessage()
Stored for a later request: in memcached, or in a cookie named dxpmessages when the site has no memcached servers
The platform's own controllers queue the messages a visitor sees after an action. Returning from an invoice payment, for example, queues an info message.
The five types
Every message has one of five types:
Type
Use
error
The action failed
warning
The action worked, with something to check
success
The action worked
info
Something the visitor should know, such as the state of a payment
debug
Detail for developers
The messages include in your theme repo, templates/includes/frontend/messages/all.html, decides which types a visitor sees. Render error, warning, success and info on every site, and debug only where developers want it.
Rendering the messages
_messages is the service itself, not a list. hasMessages() tests for any message, hasMessages('error') for one type, and getMessages('error') returns the messages of that type. Each message is an object with getMessage() (the text), getType(), and hasDeleteUrl() and getDeleteUrl(); printing the object itself prints its text.
{% if _messages is defined and _messages.hasMessages() %}
<div class="site-messages" role="status" aria-live="polite">
{% for type in ['error', 'warning', 'success', 'info'] %}
{% for message in _messages.getMessages(type) %}
<div class="message message--{{ type }}">{{ message.getMessage()|e }}</div>
{% endfor %}
{% endfor %}
</div>
{% endif %}
Include it once, from the base template, so every full page reads the queue. The isset guard (Twig is defined) lets the include sit in any template without depending on the variable. The text is escaped in both engines in case a message repeats something a visitor entered (Escaping output). To mark up one type differently, give each type its own include:
{* included from all.html: {if $_messages->hasMessages('error')}{include './error.html'}{/if} *}
{foreach $_messages->getMessages('error') as $message}
<div class="callout warning" role="alert"><strong>Error</strong> {$message->getMessage()|escape}</div>
{/foreach}
{# included from all.html when _messages.hasMessages('error') #}
{% for message in _messages.getMessages('error') %}
<div class="callout warning" role="alert"><strong>Error</strong> {{ message.getMessage()|e }}</div>
{% endfor %}
Which page shows a queued message
A redirect message is kept until a page reads it. The first request that calls hasMessages() or getMessages() takes every stored message and clears the store, so the message is shown by that request and by no other. A redirect renders no template, so it leaves the store alone:
A chain of redirects keeps the message. An action followed by three redirects and then a page shows the message on that page.
The first page that reads messages shows them. In the usual flow, an action, one redirect and a full page with the messages include, that is the very next page, which is why a message is often described as lasting one redirect.
A page that reads without printing uses them up. If a step in the middle of a flow renders a template that calls hasMessages(), the message belongs to that step.
End the flow on a rendered page
Redirect a flow to a page that is rendered for each visitor, not served from the page cache, and that includes the messages partial. A cached page is served before any template runs, so the message is shown by the next page that is rendered. Let only that final page read messages.