Cm_Diehard
Cm_Diehard copied to clipboard
Splash messages and dynamic core/messages block
It turns out having the core/messages
block which displays session messages as a dynamic block is pretty tricky.
Maybe you have a clever solution, but at the moment all I'm coming up with are very ugly hacks.
This is an issue for example in the following case:
- Visitor requests catalog/product/view page (FPC cache hit)
- Visitor adds product to cart
- POST request to checkout/cart/add page (not cached).
The method
checkout/session::addSuccess()
is called - Visitor is redirected to catalog/product/view page (no FPC cache hit since items in cart changed)
- Page is rendered,
core/messges::_prepareLayout()
andMage_Core_Controller_Varien_Action::_initLayoutMessages()
clear the session message storage adding the messages to thecore/messages
block - Messages block is rendered and cached.
But even if output is suppressed, no luck, because: - The
core/messages
block is instantiated again viaCm_Diehard_LoadController::_getResponseObject()
loading dynamic blocks - No messages are rendered since the messages in the sessions are already unset during the generic rendering of the
core/messages
block.
The only solution I've found is to persist all messages added to the initial (generic) core/messages
block, and re-add them again when the dynamic core/messages
block is rendered.
This requires a rewrite of the core/messages
block, which I would like to avoid.
I feel like I'm missing a realy elegant solution to this problem. Do you have a clean solution?
I guess the easiest solution might be to simply render the messages clientside, passing them along in a cookie. Still requires a rewrite, but should be compatible with any cache backend and work independently of Cm_Diehard.
Client side splash message rendering implementation here: https://github.com/Vinai/VinaiKopp_JsMessages Would prefer a nicer solution if you got one though.
Ahh, that is one case I hadn't thought about yet.. It is too bad Magento doesn't use the usual method of rendering this block or it would be pretty easy..
Since getMessagesBlock is implemented in a class that is already overridden in Diehard, perhaps it could be overridden to return a dummy object or the real object dependent upon the current state (if rendering a cacheable page return dummy block which renders placeholder, otherwise return real block). For the reverse proxy backends a cookie will be needed to indicate that the session has messages to be rendered. To implement this directly into Cm_Diehard I think the message block could be treated like any other with the exception that the block adds itself back to the default ignored list every time it is rendered and it is removed from the default ignored list every time a message is added. I may try this out in the Cm_DiehardSample extension sometime.
Thanks for putting up your JsMessages extension, that is also a good solution and overriding the core/messages block is not terrible since it is unlikely that any other modules will have a good reason to override this. I think storing the full message in the cookie is a bit risky in case there are length limitations, so just storing a flag and fetching the messages via Ajax might be safer, though.
One thing to watch out for is that the message block fetches and clears the core/session messages after instantiation in __prepareLayout(). I really dislike the way its implemented. (e.g. adding an event core_session_abstract_add_message and not adding the message or the session as arguments). Also, having global_messages and messages using the same block is kind of ugly, too.