[FIX] Multiple fixes to url_for

url_for now accepts a path or an uri
correctly handling shemeless uri's
url params are shadowed by keep_query

bzr revid: fme@openerp.com-20131106151752-sdov6zynz2g80uro
This commit is contained in:
Fabien Meghazi 2013-11-06 16:17:52 +01:00
parent cdd7f70308
commit 1aaf0eaa4c
1 changed files with 19 additions and 15 deletions

View File

@ -6,7 +6,7 @@ import math
import simplejson import simplejson
import traceback import traceback
import urllib import urllib
from urlparse import urljoin import urlparse
import werkzeug import werkzeug
import werkzeug.exceptions import werkzeug.exceptions
@ -53,29 +53,33 @@ def auth_method_public():
request.uid = request.session.uid request.uid = request.session.uid
http.auth_methods['public'] = auth_method_public http.auth_methods['public'] = auth_method_public
def url_for(path, lang=None, keep_query=None): def url_for(path_or_uri, lang=None, keep_query=None):
if request: location = path_or_uri.strip()
path = urljoin(request.httprequest.path, path) url = urlparse.urlparse(location)
if request and not url.netloc and not url.scheme:
location = urlparse.urljoin(request.httprequest.path, location)
langs = request.context.get('langs') langs = request.context.get('langs')
if path[0] == '/' and (len(langs) > 1 or lang): if location[0] == '/' and (len(langs) > 1 or lang):
ps = path.split('/') ps = location.split('/')
lang = lang or request.context.get('lang') lang = lang or request.context.get('lang')
if ps[1] in langs: if ps[1] in langs:
ps[1] = lang ps[1] = lang
else: else:
ps.insert(1, lang) ps.insert(1, lang)
path = '/'.join(ps) location = '/'.join(ps)
if keep_query: if keep_query:
keep = [] url = urlparse.urlparse(location)
params = werkzeug.url_decode(request.httprequest.query_string) location = url.path
params_keys = tuple(params.keys()) params = werkzeug.url_decode(url.query)
query_params = frozenset(werkzeug.url_decode(request.httprequest.query_string).keys())
for kq in keep_query: for kq in keep_query:
keep += fnmatch.filter(params_keys, kq) for param in fnmatch.filter(query_params, kq):
if keep: params[param] = request.params[param]
params = dict([(k, params[k]) for k in keep]) params = werkzeug.urls.url_encode(params)
path += u'?%s' % werkzeug.urls.url_encode(params) if params:
location += '?%s' % params
return path return location
def urlplus(url, params): def urlplus(url, params):
if not params: if not params: