Cm_Diehard icon indicating copy to clipboard operation
Cm_Diehard copied to clipboard

Splash messages and dynamic core/messages block

Open Vinai opened this issue 10 years ago • 4 comments

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:

  1. Visitor requests catalog/product/view page (FPC cache hit)
  2. Visitor adds product to cart
  3. POST request to checkout/cart/add page (not cached). The method checkout/session::addSuccess() is called
  4. Visitor is redirected to catalog/product/view page (no FPC cache hit since items in cart changed)
  5. Page is rendered, core/messges::_prepareLayout() and Mage_Core_Controller_Varien_Action::_initLayoutMessages() clear the session message storage adding the messages to the core/messages block
  6. Messages block is rendered and cached.
    But even if output is suppressed, no luck, because:
  7. The core/messages block is instantiated again via Cm_Diehard_LoadController::_getResponseObject() loading dynamic blocks
  8. 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?

Vinai avatar Jul 03 '14 12:07 Vinai

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.

Vinai avatar Jul 03 '14 12:07 Vinai

Client side splash message rendering implementation here: https://github.com/Vinai/VinaiKopp_JsMessages Would prefer a nicer solution if you got one though.

Vinai avatar Jul 03 '14 17:07 Vinai

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.

colinmollenhour avatar Jul 09 '14 15:07 colinmollenhour

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.

Vinai avatar Jul 09 '14 16:07 Vinai