mirror of
https://github.com/metosin/reitit.git
synced 2025-12-16 16:01:11 +00:00
Frontend routing implementation
This commit is contained in:
parent
4f78f56464
commit
468a0947d2
6 changed files with 107 additions and 4 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,4 +1,4 @@
|
|||
/target
|
||||
target/
|
||||
/classes
|
||||
/checkouts
|
||||
pom.xml
|
||||
|
|
|
|||
9
modules/reitit-frontend/project.clj
Normal file
9
modules/reitit-frontend/project.clj
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
(defproject metosin/reitit-frontend "0.1.3"
|
||||
:description "Reitit: Clojurescript frontend routing core"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:license {:name "Eclipse Public License"
|
||||
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-core]])
|
||||
90
modules/reitit-frontend/src/reitit/frontend.cljs
Normal file
90
modules/reitit-frontend/src/reitit/frontend.cljs
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
(ns reitit.frontend
|
||||
"Utilities to implement frontend routing using Reitit.
|
||||
|
||||
Controller is way to declare as data the side-effects and optionally
|
||||
other data related to the route."
|
||||
(:require [reitit.core :as reitit]
|
||||
[clojure.string :as str]
|
||||
goog.Uri
|
||||
[reitit.coercion :as coercion]))
|
||||
|
||||
;;
|
||||
;; Utilities
|
||||
;;
|
||||
|
||||
(defn query-params
|
||||
"Parse query-params from URL into a map."
|
||||
[^goog.Uri uri]
|
||||
(let [q (.getQueryData uri)]
|
||||
(->> q
|
||||
(.getKeys)
|
||||
(map (juxt keyword #(.get q %)))
|
||||
(into {}))))
|
||||
|
||||
(defn get-hash
|
||||
"Given browser hash starting with #, remove the # and
|
||||
end slashes."
|
||||
[]
|
||||
(-> js/location.hash
|
||||
(subs 1)
|
||||
(str/replace #"/$" "")))
|
||||
|
||||
;;
|
||||
;; Controller implementation
|
||||
;;
|
||||
|
||||
(defn get-params
|
||||
"Get controller parameters given match. If controller provides :params
|
||||
function that will be called with the match. Default is nil."
|
||||
[controller match]
|
||||
(if-let [f (:params controller)]
|
||||
(f match)))
|
||||
|
||||
(defn apply-controller
|
||||
"Run side-effects (:start or :stop) for controller.
|
||||
The side-effect function is called with controller params."
|
||||
[controller method]
|
||||
(when-let [f (get controller method)]
|
||||
(f (::params controller))))
|
||||
|
||||
(defn- pad-same-length [a b]
|
||||
(concat a (take (- (count b) (count a)) (repeat nil))))
|
||||
|
||||
(defn apply-controllers
|
||||
"Applies changes between current controllers and
|
||||
those previously enabled. Resets controllers whose
|
||||
parameters have changed."
|
||||
[old-controllers new-match]
|
||||
(let [new-controllers (map (fn [controller]
|
||||
(assoc controller ::params (get-params controller new-match)))
|
||||
(:controllers (:data new-match)))
|
||||
changed-controllers (->> (map (fn [old new]
|
||||
;; different controllers, or params changed
|
||||
(if (not= old new)
|
||||
{:old old, :new new}))
|
||||
(pad-same-length old-controllers new-controllers)
|
||||
(pad-same-length new-controllers old-controllers))
|
||||
(keep identity)
|
||||
vec)]
|
||||
(doseq [controller (map :old changed-controllers)]
|
||||
(apply-controller controller :stop))
|
||||
(doseq [controller (map :new changed-controllers)]
|
||||
(apply-controller controller :start))
|
||||
new-controllers))
|
||||
|
||||
(defn hash-change [router hash]
|
||||
(let [uri (goog.Uri/parse hash)
|
||||
match (or (reitit/match-by-path router (.getPath uri))
|
||||
{:data {:name :not-found}})
|
||||
q (query-params uri)
|
||||
;; Coerce if coercion enabled
|
||||
c (if (:result match)
|
||||
(coercion/coerce-request (:result match) {:query-params q
|
||||
:path-params (:params match)})
|
||||
{:query q
|
||||
:path (:param match)})
|
||||
;; Replace original params with coerced params
|
||||
match (-> match
|
||||
(assoc :query (:query c))
|
||||
(assoc :params (:path c)))]
|
||||
match))
|
||||
|
|
@ -11,4 +11,6 @@
|
|||
[metosin/reitit-spec]
|
||||
[metosin/reitit-schema]
|
||||
[metosin/reitit-swagger]
|
||||
[metosin/reitit-swagger-ui]])
|
||||
[metosin/reitit-swagger-ui]
|
||||
[metosin/reitit-frontend]
|
||||
[metosin/reitit-re-frame]])
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
[metosin/reitit-schema "0.1.3"]
|
||||
[metosin/reitit-swagger "0.1.3"]
|
||||
[metosin/reitit-swagger-ui "0.1.3"]
|
||||
[metosin/reitit-frontend "0.1.3"]
|
||||
|
||||
[meta-merge "1.0.0"]
|
||||
[ring/ring-core "1.6.3"]
|
||||
|
|
@ -40,7 +41,8 @@
|
|||
"modules/reitit-spec/src"
|
||||
"modules/reitit-schema/src"
|
||||
"modules/reitit-swagger/src"
|
||||
"modules/reitit-swagger-ui/src"]
|
||||
"modules/reitit-swagger-ui/src"
|
||||
"modules/reitit-frontend/src"]
|
||||
|
||||
:dependencies [[org.clojure/clojure "1.9.0"]
|
||||
[org.clojure/clojurescript "1.10.238"]
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@
|
|||
set -e
|
||||
|
||||
# Modules
|
||||
for ext in reitit-core reitit-ring reitit-spec reitit-schema reitit-swagger reitit-swagger-ui reitit; do
|
||||
for ext in reitit-core reitit-ring reitit-spec reitit-schema reitit-swagger reitit-swagger-ui reitit-frontend reitit; do
|
||||
cd modules/$ext; lein "$@"; cd ../..;
|
||||
done
|
||||
|
|
|
|||
Loading…
Reference in a new issue