How to hold a flash message even after 2 consecutive redirects? I set my flash message in my controller and there are 2 redirects happening because of a plugin which i cannot control.But still I want the flash message to be retained. I can only think of populating the message in the session.Any new ideas? help needed
which plugins? If the redirects are happening in controllers, you might be able to grab the flash message and reapply it for the next request. If the redirects are happening in plugin controllers, you can extend those controllers, configure your controller to be injected instead of the original (in resources.groovy), and handle propagating the flash message there.
If not, you can putting it in your session might be the easiest thing to do. Just make sure you test removing it from the session in the final controller action that renders the final view in the chain.
One-Time Data plugin is what you need
Related
I feel like this should be obvious, but I'm stumped. We're running Sitecore 7.1 with MVC.
There is a Header rendering that includes conditional logic depending on the status of Sitecore.Context.IsLoggedIn. Works fine.
There is a second rendering that either allows the user to log in OR displays account information. When the [HttpGet] acton is called, the controller checks IsLoggedIn and returns one of two views. When the [HttpPost] action is called (i.e. when the user logs in), The controller calls AuthenticationManager.Login() and then returns the view with the account info. Works fine.
It's a simple solution that allows us to place one rendering on the page, and it works great, except for one thing: the header rendering still shows the not-logged-in content immediately after logging in.
Caching is turned off on the header rendering and in the presentation details. When any link is clicked or the page reloads, the header updates to show the correct info. The problem is only after the initial request/response, when the login form submits and returns an alternate view. Although we've had a complete HTTP request/response cycle, it's like Sitecore doesn't bother to check anything except the rendering that was directly affected.
I know I can solve this by returning a hard Redirect() after logging in but that seems inelegant and creates annoyances, like losing ViewBag info.
What I am really looking for is a way to tell Sitecore, "hey, refresh that other rendering!"
The fact that I can find nothing at all on-line about this 'problem' tells me I might be doing something conceptually wrong.
As I see it there are two ways of handling this problem:
FormHandler
You use #Html.FormHandler to specify a Controller and an Action to handle the authentication. The FormHandler action will execute very early (see: https://twitter.com/dmo_sc/status/480001473745399809) in the page execution, before anything is rendered, and all your Renderings will have the same view of whether users are logged in or not.
Martina did a good writeup on Sitecore MVC and forms:
https://mhwelander.net/2014/05/28/posting-forms-in-sitecore-mvc-part-1-view-renderings/
https://mhwelander.net/2014/05/30/posting-forms-in-sitecore-mvc-part-2-controller-renderings/
Post-Redirect-Get
I really want Sitecore MVC to have this feature build in, as it is useful for all form submission scenarios (bar AJAX). The idea is to handle the POST request and work out what you want to respond (and store this in tempdata). Instead of returning a ViewResult you issue a redirect to the same URL, this forces a GET to the page (at this point all the logged in state is same for all Renderings) where you fish the result out of tempdata. Also P-R-G protects against resubmitting POST requests.
cprakash documented his experience doing P-R-G:
https://cprakash.com/2015/01/12/sitecore-mvc-form-post-simplified/
Off Topic: Multiple forms on single page
This will not solve the OP problem, but worth having a look at in this context:
http://reinoudvandalen.nl/blog/ultimate-fix-for-multiple-forms-on-one-page-with-sitecore-mvc/
In MVC, your renderings are executed sequentially, top to bottom. So if your header rendering comes before the login status rendering, it's going to be done before the user is logged in.
The elegant way to do this would probably be to do your post and update both elements via JavaScript. If you want to keep the header logic separate from the login status logic, your login status script could allow other components to register their own callbacks. You could even build out a client-side message bus, if you will be doing this sort of thing frequently.
You could take a look at Jeremy's approach:
https://jermdavis.wordpress.com/2016/04/04/getting-mvc-components-to-communicate/
The key takeaway, I think, is where he switches the order of the placeholders by placing the results into variables and then render them wherever you want them.
#{
HtmlString main = Html.Sitecore().Placeholder("MAIN");
HtmlString head = Html.Sitecore().Placeholder("HEAD");
}
<head>
#head
</head>
<body>
#main
</body>
I know that whenever you submit a form, you will refresh a page. But is there a way of using javascript or whatsoever that allows the webpage to refresh one more time after a submit button is being input?
Thank you guys so much.
I am guessing that what you need to implement is the Post, Redirect, Get pattern, which is the recommended way in Grails applications. if you type grails generate-controller [somedomainclassname], you will see that that controller actually employs this pattern.
It works as follows:
Your form submits to a action inside a controller, let's call it save()
Your save() action then performs the necessary operations to actually save the object, when it is done, it sends the browser a 'redirect', much like this: redirect(action: "show", id: mySavedObject.id)
This will cause the browser to issue a GET for the url /mycontroller/show/{id}
That request is picked up by the show action of your controller. It then goes on to display the object that was just created.
This approach plays well with HTTP semantics and avoids annoying "do you want to repost your form data" questions for the end user.
Using Struts 2.1.6 with Tiles.
I am noticing some strange behavior in my Struts 2 actions. I have a breakpoint set in one of the actions (say view()). When I start the application server for the first time, click a link in my web app that executes this action, the debugger stops at the break point and I can troubleshoot the problem, the exception occurs and the message is displayed on the UI.
However, when the I click on the same link again the debugger does not hit the breakpoint and the UI displays the same error message. I click other links and other debug points work completely fine. When I click again on the same URL, the same message is displayed. I have to restart the server and repeat the process again.
Is something being cached somewhere? Do you think a new instance of struts action is not being created? How do I troubleshoot this? I have not posted any code yet because I am not sure what specific information you might need...
I am storing some object in session for pagination purpose, could that be the issue?
Well what i read from your description seems like problem is somewhere in your code.With each request struts2 create a new instance of your action class as well request and response and place them in value stack, so no matter what was the result of last execution, a new request always end up creating a new instance.
Creating new instance is as per the Framework architecture as Action also work as data transfer object (model).
I suggest you to check your configuration and see where exactly is problem.
As a side note are you using Strts2-spring plugin, using the plugin you need to set scope=prototype else spring by-default will create singleton action instance and same Action instance will be used again and again
One action of one of my controllers needs to generate(redirect/render) two separate views simultaneously and show both the pages to the client. It will be like when the user submits his info, the page will redirect to a new page with a list. At the same time another page needs to pop up in a new window containing some additional info (user would print this page). I know, I can resolve the issue with a single page, but I was wondering whether there is any ways to produce two separate pages/windows simultaneously from a single controller action.
Thanks in anticipation
The simple answer is NO. Grails isn't doing anything magical. It's still constrained to normal HTTP request/response lifecycle. A single request gets a single response. What you're asking for sounds like you want grails to be able to generate 2 responses for a single HTTP request which is impossible. The response is either a page for the browser to render or it's a redirect message for the browser to go to another URL.
You could write your action that it can handle normal and ajax requests. See the docs here:
Responding to both Ajax and non-Ajax requests
Then you could generate your "normal" view. After that you call the same action by using ajax on the client side and load the data for your pop up page.
why not use a <script>window.open()</script> in your main view in order to open the popup?
Could you tell me whats the best practice to include flash messages f.e. "You must be logged out to view the requested site",
when the require_no_authentication-filter is set and the user accesses a site, which becomes filtered. The flash message should appear in every controller where i call the before filter, not only in the device controllers (so inheritance isn't enough)...
Per default there are no flash-messages, which is absurd, from my point of view.
This behaviour was changed from the device maintainers. You are now able to do that the same way the other hooks become called.