Web2py return json or redirect - redirect

In web2py, I want to set up a controller that redirects for an html view but provides a json response for a json view, e.g.
http://mysite/page.html/1234 -> redirects to http://www.google.com/q=mydata
http://mysite/page.json/1234 -> returns JSON {'1234':'my data'}
(this example assumes I have a db query that returns 'mydata' for id=1234)
I can't immediately see how to do this, as the redirect() function is called in the controller, but the decision about json or html seems to be made later, once a dict() is returned from the controller

In the controller you can use request.extension to decide whether to redirect() or return response.json(my_data).

I also found that you can set {{redirect('http://site/{}'.format(data))}} in the .html view, and it will do a proper redirect within the html file itself (and set the correct content headers). In other words, the redirect function doesn't need to be called in the controller, if that's easier.

Related

Passing data between form views in Pyramid

I'm making a project in pyramid framework, so i have a view which have a form in it with 2 input type texts and a submit button.
The form is a post method, so im getting them with a POST request.
I want to send them to a new view and display them on the screen.
meaning:
on 0.0.0.0:6543 is the form on first view.
I want to display the values the user insert in the input on 0.0.0.0:6543/here
I tried with HTTPfound but i guess im missing an understanding on how to really pass the variables.
Please help me...
The easiest way to accomplish is to use sessions.
You need a session backend which stores your data on a server (see pyramid_redis_session). There are also cookie-based session solutions where all data is stored on the client side.
The first view writes all passed over data to a session:
request.session["mydata"] = value
The second view reads data from the session
print(request.session["mydata"])
Another way to pass the data from one view to another is via the URL. This does not require server-side support, unlike sessions. Also, it's RESTful ;)
return HTTPFound('/here?greeting=Hello&subject=World')
In your second view you then simply get the variables from request.GET:
greeting = request.GET.get('greeting', '')
subject = request.GET.get('subject', '')
# pass the data to the template
return {
"greeting": greeting,
"subject": subject
}
Regarding your comment: You can't use HTTPFound with POST. You can, however, directly submit your form to /here using <form method="post" action="/here" ...>. In this case you'll be able to access the data using request.POST.get('greeting').

How to implement a POST-REDIRECT-GET in Play Framework

Let's say I have two controller methods: Users.preInsert and Users.insert. The preInsert method is the one used to display the user entry form (GET), while the insert method is responsible for the actual insertion (POST) or calling the 'insert' service.
This is how the routes looks like:
GET /users/add controllers.Users.preInsert(...)
POST /users/add controllers.Users.insert(...)
So how do I redirect a request (POST to GET) without losing the parameters like error messages returned from the insert service and the values inputed by the client so that they can be accessed and displayed in the entry form. The parameters may involve some complex objects. I have implemented it using the Caching API but I would like to know if there are any better ways of doing it.
That's the exact purpose of the Form objects (http://www.playframework.com/documentation/2.1.1/ScalaForms).
And I think there is a an error in your routes, it could look like:
GET /users/add controllers.Users.preInsert(...)
POST /users/add controllers.Users.insert(...)
You should definitively take a look at the form sample.
You don't need to redirect it back to the preInsert action, instead at the beginning of the insert check if form has errors and it it has display your view containing form (the same which you used in preInsert). It's described in the doc mentioned by nico_ekito in section Handling binding failure

POST -ing data with Laravel 4's resourceful controller does not work (store method) but works using index (GET) method. What am I doing wrong?

Hi I have a resource controller in Laravel 4. It has all the default methods generated by artisan's controller:make.
Models etc are in place.
User clicks on a link in a view that does a URL::route to a named route pointing at a controller action. It points to the 'store()' method in the controller, which is meant to be a POST method.
I write my code in the 'store()' method to handle this request. It uses eloquent to insert data into db. It returns a plain text response with HTTP code 200.
When user clicks on the above mentioned link (that points to the store() method), it seems the browser simply jumps to the index (GET) of that controller and the code doesn't run because the store() method is bypassed.
When I move all code from within the store() method into the index() method, everything works as expected.
What am I doing wrong here that my 'store()' method is not handling my code. Even when creating URL to the store action directly using URL::action, this fails.
Can someone please enlighten me?
Code:
Store method:
public function store()
{
$itemsArray = Session::get('sdata');
$cartItem = new Cart;
$cartItem->session_id = Session::get('sid');
$cartItem->items = json_encode($itemsArray);
$cartItem->save();
return Response::make('an item was added to carts', 200);
}
View:
Go
Same result for this view also:
`Go`
This is because <a> tag, is able to send only GET request. Try to create a new method, for example addToCart, and then set new rout on routes.php

HTML form POST method with querystring in action URL

Lets say I have a form with method=POST on my page.
Now this form has some basic form elements like textbox, checkbox, etc
It has action URL as http://example.com/someAction.do?param=value
I do understand that this is actually a contradictory thing to do, but my question is will it work in practice.
So my questions are;
Since the form method is POST and I have a querystring as well in my URL (?param=value)
Will it work correctly? i.e. will I be able to retrieve param=value on my receiving page (someAction.do)
Lets say I use Java/JSP to access the values on server side. So what is the way to get the values on server side ? Is the syntax same to access value of param=value as well as for the form elements like textbox/radio button/checkbox, etc ?
1) YES, you will have access to POST and GET variables since your request will contain both. So you can use $_GET["param_name"] and $_POST["param_name"] accordingly.
2) Using JSP you can use the following code for both:
<%= request.getParameter("param_name") %>
If you're using EL (JSP Expression Language), you can also get them in the following way:
${param.param_name}
EDIT: if the param_name is present in both the request QueryString and POST data, both of them will be returned as an array of values, the first one being the QueryString.
In such scenarios, getParameter("param_name) would return the first one of them (as explained here), however both of them can be read using the getParameterValues("param_name") method in the following way:
String[] values = request.getParameterValues("param_name");
For further info, read here.
Yes. You can retrieve these parameters in your action class.
Just you have to make property of same name (param in your case) with there getters and setters.
Sample Code
private String param;
{... getters and setters ...}
when you will do this, the parameters value (passed via URL) will get saved into the getters of that particular property. and through this, you can do whatever you want with that value.
The POST method just hide the submitted form data from the user. He/she can't see what data has been sent to the server, unless a special tool is used.
The GET method allows anybody to see what data it has. You can easily see the data from the URL (ex. By seeing the key-value pairs in the query string).
In other words it is up to you to show the (maybe unimportant) data to the user by using query string in the form action. For example in a data table filter. To keep the current pagination state, you can use domain.com/path.do?page=3 as an action. And you can hide the other data within the form components, like input, textarea, etc.
Both methods can be catched in the server with the same way. For example in Java, by using request.getParameter("page").

Change or switch request data

I'd like to create filter which will switch request data. More precisely i'd like to change type of request inside filter (it have to be POST), add some values into post's Data, add return url, and redirect it to Controller's action which accepts only POST... and then in this action i'd like to return to first URL.
I've found something like...
Response.Redirect with POST instead of Get?
but i'm pretty sure i don't catch his idea completely and don't know is it useful in FIlter.
I've not found how to change request data... but useful was to
var controller = new MyController();
controller.ControllerContext = filterContext.Controller.ControllerContext;
controller.<action>(<parameters>); // it's action which accepts only POST, but here it doesn't matter
base.OnActionExecuting(filterContext);
Is there any better way to pass context or mayby... invoke Controller from current context? instead of creating new controller and calling his action?