From 1923f2d08e2342998e192037d476c12f8b921d3c Mon Sep 17 00:00:00 2001 From: Tommi Reiman Date: Thu, 14 Jun 2018 17:52:57 +0300 Subject: [PATCH] handle query-parameters in reverse routing --- CHANGELOG.md | 16 ++++++++++++++++ modules/reitit-core/src/reitit/core.cljc | 6 ++++++ modules/reitit-core/src/reitit/impl.cljc | 7 +++++++ test/cljc/reitit/core_test.cljc | 11 +++++++++++ test/cljc/reitit/impl_test.cljc | 16 ++++++++++++++++ 5 files changed, 56 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f223f96..5aa591cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,22 @@ ; :query {:int 10}} ``` +* `reitit.core/match->path` to create full paths from match, including the query parameters: + +```clj +(require '[reitit.core :as r]) + +(-> (r/router ["/:a/:b" ::route]) + (r/match-by-name! ::route {:a "olipa", :b "kerran"}) + (r/match->path)) +; "/olipa/kerran" + +(-> (r/router ["/:a/:b" ::route]) + (r/match-by-name! ::route {:a "olipa", :b "kerran"}) + (r/match->path {:iso "pöriläinen"})) +; "/olipa/kerran?iso=p%C3%B6ril%C3%A4inen" +``` + ## 0.1.2 (2018-6-6) ### `reitit-core` diff --git a/modules/reitit-core/src/reitit/core.cljc b/modules/reitit-core/src/reitit/core.cljc index b3785447..2a22f1a7 100644 --- a/modules/reitit-core/src/reitit/core.cljc +++ b/modules/reitit-core/src/reitit/core.cljc @@ -129,6 +129,12 @@ (impl/throw-on-missing-path-params (:template match) (:required match) path-params))))) +(defn match->path + ([match] + (match->path match nil)) + ([match query-params] + (some-> match :path (cond-> query-params (str "?" (impl/query-string query-params)))))) + (def default-router-options {:lookup name-lookup :expand expand diff --git a/modules/reitit-core/src/reitit/impl.cljc b/modules/reitit-core/src/reitit/impl.cljc index 49409265..003f2870 100644 --- a/modules/reitit-core/src/reitit/impl.cljc +++ b/modules/reitit-core/src/reitit/impl.cljc @@ -209,3 +209,10 @@ (assoc m k (url-encode (into-string v)))) {} params)) + +(defn query-string + "shallow transform of query parameters into query string" + [params] + (->> params + (map (fn [[k v]] (str (url-encode (into-string k)) "=" (url-encode (into-string v))))) + (str/join "&"))) diff --git a/test/cljc/reitit/core_test.cljc b/test/cljc/reitit/core_test.cljc index f8233888..f1a27584 100644 --- a/test/cljc/reitit/core_test.cljc +++ b/test/cljc/reitit/core_test.cljc @@ -246,3 +246,14 @@ [["/a"] ["/a"]])))) (testing "can be configured to ignore" (is (not (nil? (r/router [["/a"] ["/a"]] {:conflicts (constantly nil)}))))))) + +(deftest match->path-test + (let [router (r/router ["/:a/:b" ::route])] + (is (= "/olipa/kerran" + (-> router + (r/match-by-name! ::route {:a "olipa", :b "kerran"}) + (r/match->path)))) + (is (= "/olipa/kerran?iso=p%C3%B6ril%C3%A4inen" + (-> router + (r/match-by-name! ::route {:a "olipa", :b "kerran"}) + (r/match->path {:iso "pöriläinen"})))))) diff --git a/test/cljc/reitit/impl_test.cljc b/test/cljc/reitit/impl_test.cljc index 1f669b83..1d437ed8 100644 --- a/test/cljc/reitit/impl_test.cljc +++ b/test/cljc/reitit/impl_test.cljc @@ -48,3 +48,19 @@ :k :kikka :qk ::kikka :nil nil})))) + +(deftest query-params-test + (are [x y] + (= (impl/query-string x) y) + {:a "b"} "a=b" + {"a" "b"} "a=b" + {:a 1} "a=1" + {:a nil} "a=" + {:a :b :c "d"} "a=b&c=d" + {:a "b c"} "a=b%20c")) + +; TODO: support seq values? +;{:a ["b" "c"]} "a=b&a=c" +;{:a ["c" "b"]} "a=c&a=b" +;{:a (seq [1 2])} "a=1&a=2" +;{:a #{"c" "b"}} "a=b&a=c"