mirror of
https://github.com/metosin/reitit.git
synced 2025-12-21 10:01:11 +00:00
Merge pull request #332 from nilern/frontend-multi-query-params
Frontend: Multi-valued query params
This commit is contained in:
commit
0faf2af876
5 changed files with 38 additions and 13 deletions
|
|
@ -17,6 +17,11 @@ We use [Break Versioning][breakver]. The version numbers follow a `<major>.<mino
|
||||||
### `reitit-core`
|
### `reitit-core`
|
||||||
|
|
||||||
* Added ability to mark individual routes as conflicting by using `:conflicting` route data. See [documentation](https://metosin.github.io/reitit/basics/route_conflicts.html). Fixes [#324](https://github.com/metosin/reitit/issues/324)
|
* Added ability to mark individual routes as conflicting by using `:conflicting` route data. See [documentation](https://metosin.github.io/reitit/basics/route_conflicts.html). Fixes [#324](https://github.com/metosin/reitit/issues/324)
|
||||||
|
* Encode sequential and set values as multi-valued query params (e.g. `{:foo ["bar", "baz"]}` => foo=bar&foo=baz).
|
||||||
|
|
||||||
|
### `reitit-frontend`
|
||||||
|
|
||||||
|
* Decode multi-valued query params correctly into seqs (e.g. foo=bar&foo=baz => `{:foo ["bar", "baz"]}`).
|
||||||
|
|
||||||
## 0.3.10 (2019-10-8)
|
## 0.3.10 (2019-10-8)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@
|
||||||
|
|
||||||
(defn resolve-routes [raw-routes {:keys [coerce] :as opts}]
|
(defn resolve-routes [raw-routes {:keys [coerce] :as opts}]
|
||||||
(cond->> (->> (walk raw-routes opts) (map-data merge-data))
|
(cond->> (->> (walk raw-routes opts) (map-data merge-data))
|
||||||
coerce (into [] (keep #(coerce % opts)))))
|
coerce (into [] (keep #(coerce % opts)))))
|
||||||
|
|
||||||
(defn path-conflicting-routes [routes opts]
|
(defn path-conflicting-routes [routes opts]
|
||||||
(-> (into {}
|
(-> (into {}
|
||||||
|
|
@ -239,14 +239,19 @@
|
||||||
[params]
|
[params]
|
||||||
(maybe-map-values #(url-encode (into-string %)) params))
|
(maybe-map-values #(url-encode (into-string %)) params))
|
||||||
|
|
||||||
|
(defn- query-parameter [k v]
|
||||||
|
(str (form-encode (into-string k))
|
||||||
|
"="
|
||||||
|
(form-encode (into-string v))))
|
||||||
|
|
||||||
(defn query-string
|
(defn query-string
|
||||||
"shallow transform of query parameters into query string"
|
"shallow transform of query parameters into query string"
|
||||||
[params]
|
[params]
|
||||||
(->> params
|
(->> params
|
||||||
(map (fn [[k v]]
|
(map (fn [[k v]]
|
||||||
(str (form-encode (into-string k))
|
(if (or (sequential? v) (set? v))
|
||||||
"="
|
(str/join "&" (map query-parameter (repeat k) v))
|
||||||
(form-encode (into-string v)))))
|
(query-parameter k v))))
|
||||||
(str/join "&")))
|
(str/join "&")))
|
||||||
|
|
||||||
(defmacro goog-extend [type base-type ctor & methods]
|
(defmacro goog-extend [type base-type ctor & methods]
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,14 @@
|
||||||
[reitit.coercion :as coercion]
|
[reitit.coercion :as coercion]
|
||||||
[reitit.coercion :as rc]
|
[reitit.coercion :as rc]
|
||||||
[reitit.core :as r])
|
[reitit.core :as r])
|
||||||
(:import goog.Uri))
|
(:import goog.Uri
|
||||||
|
goog.Uri.QueryData))
|
||||||
|
|
||||||
|
(defn- query-param [^goog.Uri.QueryData q k]
|
||||||
|
(let [vs (.getValues q k)]
|
||||||
|
(if (< (alength vs) 2)
|
||||||
|
(aget vs 0)
|
||||||
|
(vec vs))))
|
||||||
|
|
||||||
(defn query-params
|
(defn query-params
|
||||||
"Given goog.Uri, read query parameters into Clojure map."
|
"Given goog.Uri, read query parameters into Clojure map."
|
||||||
|
|
@ -11,7 +18,7 @@
|
||||||
(let [q (.getQueryData uri)]
|
(let [q (.getQueryData uri)]
|
||||||
(->> q
|
(->> q
|
||||||
(.getKeys)
|
(.getKeys)
|
||||||
(map (juxt keyword #(.get q %)))
|
(map (juxt keyword #(query-param q %)))
|
||||||
(into {}))))
|
(into {}))))
|
||||||
|
|
||||||
(defn match-by-path
|
(defn match-by-path
|
||||||
|
|
|
||||||
|
|
@ -51,13 +51,11 @@
|
||||||
{:a 1} "a=1"
|
{:a 1} "a=1"
|
||||||
{:a nil} "a="
|
{:a nil} "a="
|
||||||
{:a :b :c "d"} "a=b&c=d"
|
{:a :b :c "d"} "a=b&c=d"
|
||||||
{:a "b c"} "a=b+c"))
|
{:a "b c"} "a=b+c"
|
||||||
|
{:a ["b" "c"]} "a=b&a=c"
|
||||||
; TODO: support seq values?
|
{:a ["c" "b"]} "a=c&a=b"
|
||||||
;{:a ["b" "c"]} "a=b&a=c"
|
{:a (seq [1 2])} "a=1&a=2"
|
||||||
;{:a ["c" "b"]} "a=c&a=b"
|
{:a #{"c" "b"}} "a=b&a=c"))
|
||||||
;{:a (seq [1 2])} "a=1&a=2"
|
|
||||||
;{:a #{"c" "b"}} "a=b&a=c"
|
|
||||||
|
|
||||||
;; test from https://github.com/playframework/playframework -> UriEncodingSpec.scala
|
;; test from https://github.com/playframework/playframework -> UriEncodingSpec.scala
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,16 @@
|
||||||
:path {}}})
|
:path {}}})
|
||||||
(rf/match-by-path router "/foo")))
|
(rf/match-by-path router "/foo")))
|
||||||
|
|
||||||
|
(is (= (r/map->Match
|
||||||
|
{:template "/foo"
|
||||||
|
:data {:name ::foo}
|
||||||
|
:path-params {}
|
||||||
|
:query-params {:mode ["foo", "bar"]}
|
||||||
|
:path "/foo"
|
||||||
|
:parameters {:query {:mode ["foo", "bar"]}
|
||||||
|
:path {}}})
|
||||||
|
(rf/match-by-path router "/foo?mode=foo&mode=bar")))
|
||||||
|
|
||||||
(is (= "/foo"
|
(is (= "/foo"
|
||||||
(r/match->path (rf/match-by-name router ::foo))))
|
(r/match->path (rf/match-by-name router ::foo))))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue