Pylons/Routes rewrite POST or GET to fancy URL - python

The behavior I propose:
A user loads up my "search" page, www.site.com/search, types their query into a form, clicks submit, and then ends up at www.site.com/search/the+query instead of www.site.com/search?q=the+query. I've gone through a lot of the Pylons documentation already and just finished reading the Routes documentation and am wondering if this can/should happen at the Routes layer. I have already set up my application to perform a search when given www.site.com/search/the+query, but can not figure out how to send a form to this destination.
Or is this something that should happen inside a controller with a redirect_to()?
Or somewhere else?
Followup:
This is less an actual "set in stone" desire right now and more a curiosity for brainstorming future features. I'm designing an application which uses a Wikipedia dump and have observed that when a user performs a search on Wikipedia and the search isn't too ambiguous it redirects directly to an article link: en.wikipedia.org/wiki/Apple. It is actually performing an in-between HTTP 302 redirect step, and I am just curious if there's a more elegant/cute way of doing this in Pylons.

You can send whatever content you want for any URL, but if you want a particular URL to appear in the browser's address bar, you have to use a redirect. This is independent of whether you use Pylons, Django or Rails on the server side.
In the handling for /search (whether POST or GET), one would normally run the query in the back end, and if there was only one search result (or one overwhelmingly relevant result) you would redirect to that result, otherwise to a page showing links to the top N results. That's just normal practice, AFAIK.

HTML forms are designed to go to a specific URL with a query string (?q=) or an equivalent body in a POST -- either you write clever and subtle Javascript to intercept the form submission and rewrite it in your preferred weird way, or use redirect_to (and the latter will take some doing).
But why do you need such weird behavior rather than just following the standard?! Please explain your use case in terms of application-level needs...!

Related

Which HTTP method should I use to update a session attribute?

If I have a view which the only purpose is to update a value in my session, is it safe to use it over GET or should I use POST and CSRF protection?
The value modified in the session is only used to change the user's context and if somebody manage to change the user's context in his own browser that should be harmless.
I personally don't ever consider it safe to use GET for a request that will have side effects.
I try to always follow the practice of POST + redirection to another page.
This solves all kinds of problems, such as F5 refreshing the action, the user bookmarking a URL which has a side effect and so on.
In your case, the update is harmless, but using POST at least conveys the fact that it's an update and may be useful for tools such as caching software (POST requests usually aren't cached).
On top of that, applications often change, and you may at some point need to modify the app in such a way that the update isn't so harmless anymore.
It's also generally difficult to guarantee that anything is completely secure in web development, so I prefer to stay on the safe side.

Django Redirect URL

I am new to Django, and i am now trying to use the HttpResponseRedirect() function. But I am so confused that if I use it like HttpResponseRedirect('good/'), and the current page is '/bad/', it can only be redirected to '/bad/good/', which is an url of current page appended with the url value from the HttpResponseRedirect() function. I tried to search google, and could not find any solution.
How can I redirect to the page with specific url? For example, HttpResponseRedirect('/good/') to /good/ rather than /bad/good/ ?
Surely you must see that there's a difference between 'good/' and '/good/'? The former will always add itself onto the existing page, whereas the latter will start from the root. This is basic web behaviour, and nothing to do with Django.
In any case, you should never hard-code URLs like that, but should use Django's URL-reversing functionality to calculate the URLs dynamically.
If you want to redirect to urls in your domain, you can use redirect. You can use redirect to view with by using patterns in your urls.py file or to any urls you 'd like. Although I strongly encourage the usage of views as indicates the different tutorials available on their website.
Better check out django documentation that is one of the most complete out there (to my humble opinion)
/edit for lack of clarity indeed.

Checking login status at every page load in CherryPy

I am in the midst of writing a web app in CherryPy. I have set it up so that it uses OpenID auth, and can successfully get user's ID/email address.
I would like to have it set so that whenever a page loads, it checks to see if the user is logged in, and if so displays some information about their login.
As I see it, the basic workflow should be like this:
Is there a userid stored in the current session? If so, we're golden.
If not, does the user have cookies with a userid and login token? If so, process them, invalidate the current token and assign a new one, and add the user information to the session. Once again, we're good.
If neither condition holds, display a "Login" link directing to my OpenID form.
Obviously, I could just include code (or a decorator) in every public page that would handle this. But that seems very... irritating.
I could also set up a default index method in each class, which would do this and then use a (page-by-page) helper method to display the rest of the content. But this seems like a nightmare when it comes to the occasional exposed method other than index.
So, my hope is this: is there a way in CherryPy to set some code to be run whenever a request is received? If so, I could use this to have it set up so that the current session always includes all the information I need.
Alternatively, is it safe to create a wrapper around the cherrypy.expose decorator, so that every exposed page also runs this code?
Or, failing either of those: I'm also open to suggestions of a different workflow. I haven't written this kind of system before, and am always open to advice.
Edit: I have included an answer below on how to accomplish what I want. However, if anybody has any workflow change suggestions, I would love the advice! Thanks all.
Nevermind, folks. Turns out that this isn't so bad to do; it is simply a matter of doing the following:
Write a function that does what I want.
Make the function in to a custom CherryPy Tool, set to the before_handler hook.
Enable that tool globally in my config.

How the url internationalization should be made?

I have a question regarding the internationalization of a website's URL addresses.
The question is how to make it properly?
What I would like to do is something like this.
Assume you have an URL in your address bar
www.mydomain.com/en/book
then if you type www.mydomain.com/de/book you will be redirected to a german version of a site so the url will change to www.mydomain.com/de/buch and so on.
Idea:
I thought about making a table that would be used as a dictionary between different languages. For the website content I would still use i18n, but I think that for urls it cannot be applied.
The implementation:
I thought about modifying routing.py in a way that before any connection is invoked I would recognize in the URL a language that user wants, and store it in a session variable for later use with i18n. Then I would redirect user to a correct url for this lanugage and invoke a poper controller/action.
Any ideas, suggestions or recomendations are welcome.
Edit (2011-04-04 18:35):
I have just reminded myself that I have already encountered a similar problem on Opera Blog;
there is a problem on StackOverflow: Pylons application Internationalization, but it deals solely on site internationalization, no problem with URLs included;
WZeberaFFS has pointed our a small issue that may arise if no reference or previous language settings are taken into account;
Additional question: What should be stored in database, to make it work fast? I have my own idea, but I will give it a try later on.
I believe your implementation will work as log as you don't have the same name of to different pages like if you have a page called www.mydomain.com/en/music and if music in German is book, then the problem will be that if you want to go to www.mydomain.com/fr/music then you don't know if you are coming form /de/ or /en/. But this is only a problem if you have colliding names on different pages cross languish it will still work if you have the same name for a word in 2 different languish you wont really know where they cam form but you will know where they are heading.
If you have that problem then you have to save a session or hope that the client sends a referral.
I have no idea how it could be done in Python, but usually people do such things through some kind of URL Re-writer or URL filter - something that will consume your URL and re-direct to proper page setting Locale at the same time.

django: search forms and redirect

After processing form from POST I should redirect, to prevent user from hitting back. However, I am using form to determine search query on a database, so I need to either pass params to the redirected site or the result of a search. Or maybe there is some other good practice, how to solve this problem? Maybe in this situation I am allowed not to redirect (nothing happens, if user performs search again).
Search queries should probably be GETs, rather than POSTs, because they are not changing anything - they are simply passing parameters to get certain information. POST should be reserved for forms that actually change things in the database, or result in a specific action (eg submitting an email).
To reply to your comment, hiding parameters from URLs is not particularly good practice, but if you really think you need to, this is an instance where it's OK not to redirect after the form submission - again, because you're not affecting anything with the POST.

Categories