In an environment with many different controllers like Neos (with plugins) using flashmessages is very difficult as the messages might appear in places they are not intended for.
Therefore I suggest to introduce scope to the flash message container.
Rough behavior would be the following:
add/get/flush would get an additional (optional) $scope argument that can be an arbitrary string.
if null/not given all methods will behave as now but won’t touch any scoped messages.
If you add the $scope argument you will just interact with your scope, so messages are added to your scope, get will only return messages of your scope, flush will only flush messages of your scope and so on.
Should be fairly simple to implement and help using flashmessages in plugins.
I have my issues with the current usage of FlashMessages, too. But frankly I don’t think that making the concept more versatile will solve the issue.
Let’s get to the core of it:
the messages might appear in places they are not intended for.
Is the reason for this really scoping?
AFAIU the idea of a flash message is to display messages to the user on the “next screen” whatever the context is.
The problems of accumulated flash messages usually originate in them not being rendered consistently.
So we should communicate that if you have to make sure to always render FlashMessages once you use them (as in: add
<f:flashMessages /> to your layouts)
Some (not exactly related) issues I have with the current implementation/usage:
- Using FlashMessages creates a session. Always.
- Using FlashMessages in Controller code mixes concerns and makes the Controller unusable for other formats
- No built-in i18n support
It’s not only a question about “the next page” and frequently clearing but think about Neos. You might have a huge website with plugins and multiple templates. I might want to use flashmessages in each of the plugin contexts because putting everything globally might be confusing.
I mean I am also fine with removing the concept, I agree it’s not optimal. But right now it looks like solving a use case that it cannot really solve in a neos context IMHO.
I wasn’t very clear. I didn’t suggest to completely get rid of the concept. But IMO we should spend some time thinking about how we could improve it in general.
I might want to use flashmessages in each of the plugin contexts
So you want to display the message only in the plugin template?
One could argue that it’s not really a flash message in the strict sense then, but I don’t want to split hairs. I just wonder: is that really a common scenario and wouldn’t it in general be more UX friendly to display those system messages in a unified style?
(I’m just thinking out load, of course it depends on what the clients wants).
Sorry for highjacking the thread, but here are some rough ideas on how we could avoid the other issues. And maybe that will turn out to relate to the scoping issue and/or make it easier to solve:
Using FlashMessages creates a session. Always.
Sessions are not bad per se, but it’s an overkill for flash messages if your application is stateless otherwise and it should at least be configurable IMO.
A common solution in major applications is to pass the message via query arguments.
Sometimes as simple as
Instead of the message it’s probably wise to send some message code instead. And that could solve the missing i18n support at the same time.
This mechanism could of course be used to solve the scoping issue by namespacing the argument.
Using FlashMessages in Controller code mixes concerns
This one is really unrelated, but I think it would be nice to be able to specify possible flash messages outside of the controller code as some kind of “rules engine”.
When working with Domain events (not necessarily Event sourcing) this can be achieved by event listeners that create the flashmessages if the context fits (http request)
I’m with Bastian regarding the definition of “Flash Message”, but I can still see the need to “scope” that concept.
Like say you have an application with frontend and backend, and you have a flash message occur due to some backend action (possibly triggered through an ajax request), then you don’t always want that flash message be possible to pop up when looking at a frontend page, just because you reload that in a different tab and it loads quicker than the next backend page. Maybe not the best example, but well…
Though it could indeed be, that this issue only stems from the current Session based implementation. The session just doesn’t guarantee that the message is shown on “the next page”, only “on any next page that renders the message”.
So is the contract of a Flash Message: “next-page-or-never” or “eventually”?
Another option to avoid the session would be to just use a cookie.
That would still have same behaviour as the session based solution. Also note that setting a cookie will bypass cache proxies.
I do like the strategy to add an URL parameter, it should solve most issues (though probably introduce new ones because how would that work in the above ajax request use case?).
I think that’s a good example and exactly why I don’t like the hard-coded session approach.
The ajax handler should be able to render the flash message (or discard it).
With the difference that a) it is stateless and b) it can be consumed by the client-side (see above)
Good point! In any case this should be just one option IMO.
Also we might be able to use different HTTP headers like
X-Flow-FlashMessage or sth. But I’m not sure if that works with redirects.