mirror of
https://github.com/metosin/reitit.git
synced 2025-12-22 18:41:10 +00:00
Implement #238, handle trailing slashes in frontend match-by-path
This commit is contained in:
parent
3644c2e392
commit
c86f042f54
2 changed files with 106 additions and 4 deletions
|
|
@ -1,5 +1,6 @@
|
|||
(ns reitit.frontend
|
||||
(:require [clojure.set :as set]
|
||||
[clojure.string :as str]
|
||||
[reitit.coercion :as coercion]
|
||||
[reitit.coercion :as rc]
|
||||
[reitit.core :as r])
|
||||
|
|
@ -16,10 +17,18 @@
|
|||
|
||||
(defn match-by-path
|
||||
"Given routing tree and current path, return match with possibly
|
||||
coerced parameters. Return nil if no match found."
|
||||
coerced parameters. Returns nil if no match found."
|
||||
[router path]
|
||||
(let [uri (.parse Uri path)]
|
||||
(if-let [match (r/match-by-path router (.getPath uri))]
|
||||
(let [uri (.parse Uri path)
|
||||
path (.getPath uri)]
|
||||
(if-let [match (or (r/match-by-path router path)
|
||||
(if-let [trailing-slash-handling (:trailing-slash-handling (r/options router))]
|
||||
(if (str/ends-with? path "/")
|
||||
(if (not= trailing-slash-handling :add)
|
||||
(r/match-by-path router (subs path 0 (dec (count path)))))
|
||||
(if (not= trailing-slash-handling :remove)
|
||||
(r/match-by-path router (str path "/"))))))]
|
||||
;; User can update browser location in on-navigate call using replace-state
|
||||
(let [q (query-params uri)
|
||||
match (assoc match :query-params q)
|
||||
;; Return uncoerced values if coercion is not enabled - so
|
||||
|
|
@ -40,7 +49,14 @@
|
|||
|
||||
(defn router
|
||||
"Create a `reitit.core.router` from raw route data and optionally an options map.
|
||||
Enables request coercion. See [[reitit.core/router]] for details on options."
|
||||
Enables request coercion. See [[reitit.core/router]] for details on options.
|
||||
|
||||
Additional options:
|
||||
|
||||
| key | description |
|
||||
| -------------|-------------|
|
||||
| :trailing-slash-handling | TODO |
|
||||
"
|
||||
([raw-routes]
|
||||
(router raw-routes {}))
|
||||
([raw-routes opts]
|
||||
|
|
|
|||
|
|
@ -104,3 +104,89 @@
|
|||
(capture-console
|
||||
(fn []
|
||||
(rf/match-by-name! router ::foo {}))))))))))
|
||||
|
||||
|
||||
(deftest trailing-slash-handling-test
|
||||
(testing ":both"
|
||||
(let [router (r/router ["/"
|
||||
["" ::frontpage]
|
||||
["foo" ::foo]
|
||||
["bar/" ::bar]]
|
||||
{:trailing-slash-handling :both})]
|
||||
(is (= (r/map->Match
|
||||
{:template "/foo"
|
||||
:data {:name ::foo}
|
||||
:path-params {}
|
||||
:query-params {}
|
||||
:path "/foo"
|
||||
:parameters {:query {}
|
||||
:path {}}})
|
||||
(rf/match-by-path router "/foo/")
|
||||
(rf/match-by-path router "/foo")))
|
||||
|
||||
(is (= (r/map->Match
|
||||
{:template "/bar/"
|
||||
:data {:name ::bar}
|
||||
:path-params {}
|
||||
:query-params {}
|
||||
:path "/bar/"
|
||||
:parameters {:query {}
|
||||
:path {}}})
|
||||
(rf/match-by-path router "/bar/")
|
||||
(rf/match-by-path router "/bar"))) ))
|
||||
|
||||
(testing ":add"
|
||||
(let [router (r/router ["/"
|
||||
["" ::frontpage]
|
||||
["foo" ::foo]
|
||||
["bar/" ::bar]]
|
||||
{:trailing-slash-handling :add})]
|
||||
(is (= (r/map->Match
|
||||
{:template "/foo"
|
||||
:data {:name ::foo}
|
||||
:path-params {}
|
||||
:query-params {}
|
||||
:path "/foo"
|
||||
:parameters {:query {}
|
||||
:path {}}})
|
||||
(rf/match-by-path router "/foo")))
|
||||
(is (nil? (rf/match-by-path router "/foo/")))
|
||||
|
||||
(is (= (r/map->Match
|
||||
{:template "/bar/"
|
||||
:data {:name ::bar}
|
||||
:path-params {}
|
||||
:query-params {}
|
||||
:path "/bar/"
|
||||
:parameters {:query {}
|
||||
:path {}}})
|
||||
(rf/match-by-path router "/bar/")
|
||||
(rf/match-by-path router "/bar")))))
|
||||
|
||||
(testing ":remove"
|
||||
(let [router (r/router ["/"
|
||||
["" ::frontpage]
|
||||
["foo" ::foo]
|
||||
["bar/" ::bar]]
|
||||
{:trailing-slash-handling :remove})]
|
||||
(is (= (r/map->Match
|
||||
{:template "/foo"
|
||||
:data {:name ::foo}
|
||||
:path-params {}
|
||||
:query-params {}
|
||||
:path "/foo"
|
||||
:parameters {:query {}
|
||||
:path {}}})
|
||||
(rf/match-by-path router "/foo/")
|
||||
(rf/match-by-path router "/foo")))
|
||||
|
||||
(is (= (r/map->Match
|
||||
{:template "/bar/"
|
||||
:data {:name ::bar}
|
||||
:path-params {}
|
||||
:query-params {}
|
||||
:path "/bar/"
|
||||
:parameters {:query {}
|
||||
:path {}}})
|
||||
(rf/match-by-path router "/bar/")))
|
||||
(is (nil? (rf/match-by-path router "/bar"))))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue