Mike Orr  committed c25b5af

Fix bug handling existing query params; add support for multiple values.

  • Participants
  • Parent commits 2ee1c97
  • Branches trunk

Comments (0)

Files changed (3)

   - Urlencode ``urlify()`` return value in case it contains special
     characters like "?". Reported by
+* webhelpers.util:
+  - Fix bug in handling existing query strings. Support multiple values per
+    parameter.
 1.1 (2010-08-09)

File docs/whats_new.rst

 "MarkupSafe" package, which Mako and Pylons have also switched to.  MarkupSafe
 has a C speedup for escaping, escapes single-quotes for greater security (to
 close a potential XSS attack route), and adds new methods to ``literal``.
-* **literal** is now a subclass of ``markupsafe.Markup``
-* **escape** is ``markupsafe.escape_silent``
-*Note*: ``escape_silent`` does not exist yet in MarkupSafe 0.9.3, but
-WebHelpers has a fallback. 
+**literal** is now a subclass of ``markupsafe.Markup``
+**escape** is ``markupsafe.escape_silent``
+(Note: ``escape_silent`` does not exist yet in MarkupSafe 0.9.3, but
+WebHelpers has a fallback.)
 *webhelpers.html.tags:* The ``text()`` helper has a "type" argument for new
 HTML 5 input types.
 generated by the ``form()`` helper**: the IDs clash if there are multiple forms
 on the page. To create a hidden field with an ID, call ``hidden()`` directly.
+*webhelpers.util:* ``update_params`` now supports query parameters with
+multiple values.
 Version 1.1

File webhelpers/

     from cgi import parse_qs
-def update_params(url, **params):
+def update_params(_url, _debug=False, **params):
     """Update query parameters in a URL.
-    ``url`` is any URL.
-    ``params`` are query parameters to add or replace. If any value is None,
-    the corresponding parameter is deleted from the URL if present.
+    ``_url`` is any URL, with or without a query string.
+    ``\*\*params`` are query parameters to add or replace. Each value may be a
+    string, a list of strings, or None. Passing a list generates multiple
+    values for the same parameter. Passing None deletes the corresponding
+    parameter if present.
     Return the new URL.
-    This function does not handle multiple parameters with the same name.
-    It will arbitrarily choose one value and discard the others.
     *Debug mode:* if a pseudo-parameter ``_debug=True`` is passed,
     return a tuple: ``[0]`` is the URL without query string or fragment,
     ``[1]`` is the final query parameters as a dict, and ``[2]`` is the
     >>> update_params("", new1="NEW1", _debug=True)
     ('', {'new1': 'NEW1'}, 'myfrag')
+    >>> update_params("", brrr=3)
+    ''
+    >>> update_params("", foo=["C", "D"])
+    ''
-    debug = params.pop("_debug", False)
-    orig_url = url
-    url, fragment = urlparse.urldefrag(url)
+    url, fragment = urlparse.urldefrag(_url)
     if "?" in url:
         url, qs = url.split("?", 1)
         query = parse_qs(qs)
             query[key] = value
         elif key in query:
             del query[key]
-    if debug:
+    if _debug:
         return url, query, fragment
-    qs = urllib.urlencode(query)
+    qs = urllib.urlencode(query, True)
     if qs:
         qs = "?" + qs
     if fragment: