In Python I would do the following:
>>> q = urllib.urlencode({"q": "clojure url"})
>>> q
'q=clojure+url'
>>> url = "http://stackoverflow.com/search?" + q
>>> url
'http://stackoverflow.com/search?q=clojure+url'
How do I do all the encoding that's done for me above in Clojure? In other words, how do I do something akin to the following:
=> (build-url "http://stackoverflow.com/search" {"q" "clojure url"})
"http://stackoverflow.com/search?q=clojure+url"
There is a url-encode
function in Ring's ring.util.codec
namespace:
(ring.util.codec/url-encode "clojure url")
; => "clojure+url"
I'm not sure if there's a prepackaged function to turn a map into a query string, but perhaps this could do the job:
(use '[ring.util.codec :only [url-encode]])
(defn make-query-string [m]
(->> (for [[k v] m]
(str (url-encode k) "=" (url-encode v)))
(interpose "&")
(apply str)))
An example:
user> (make-query-string {"q" "clojure url" "foo" "bar"})
"q=clojure+url&foo=bar"
All that remains is concatenating the result onto the end of a URL:
(defn build-url [url-base query-map]
(str url-base "?" (make-query-string query-map)))
Seems to work:
user> (build-url "http://stackoverflow.com/search" {"q" "clojure url"})
"http://stackoverflow.com/search?q=clojure+url"
Update:
Perhaps a modified version might make for a more Clojure-friendly experience. Also handles encoding via a Ring-style optional argument with utf-8 as default.
(defn make-query-string [m & [encoding]]
(let [s #(if (instance? clojure.lang.Named %) (name %) %)
enc (or encoding "UTF-8")]
(->> (for [[k v] m]
(str (url-encode (s k) enc)
"="
(url-encode (str v) enc)))
(interpose "&")
(apply str))))
(defn build-url [url-base query-map & [encoding]]
(str url-base "?" (make-query-string query-map encoding)))
So now we can do
user> (build-url "http://example.com/q" {:foo 1})
"http://example.com/q?foo=1"
Here's one way:
user=> (import [java.net URLEncoder])
java.net.URLEncoder
user=> (str "http://stackoverflow.com/search?q=" (URLEncoder/encode "clojure url" "UTF-8"))
"http://stackoverflow.com/search?q=clojure+url"
I know this is not exactly the same as your Python snippet though. Please see the following post from the Clojure mailing list for a more complete answer:
http://www.mail-archive.com/[email protected]/msg29338.html
The code from there will allow you to do this:
user=> (encode-params {"q" "clojure url"})
"q=clojure+url"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With