blob: cab8f3378d685335e6b91d7c210d2d6a26a9add6 (
about) (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
(ns reverse-routing.core
(:require clout.core
compojure.core
[clojure.string :as string]))
(def ^:private ^:dynamic *reverse-routes* nil)
(def ^:private ^:dynamic *root* nil)
(defn wrap-reverse-routing [handler & {:keys [root] :or {:root ""}}]
(fn [request]
(binding [*reverse-routes* (->> handler meta ::routes)
*root* root]
(handler request))))
(defn ^:private routing [request & handlers]
(some #(% request) handlers))
(defmacro routes [& handlers]
(let [routes-map (->> handlers
(map (comp ::routes meta macroexpand))
(into {}))]
(vary-meta `(vary-meta (fn [request#]
(#'routing request# ~@handlers))
assoc ::routes ~routes-map)
assoc ::routes routes-map)))
(defmacro defroutes [name & handlers]
`(def ~name (routes ~@handlers)))
(defmacro context [path args & routes]
(let [string-path (if (vector? path) (first path) path)
routes-map (let [path-keys (:keys (clout.core/route-compile string-path))
keylen (count path-keys)]
(->> (for [route (map (comp ::routes meta macroexpand) routes)
[[path num] {:keys [uri args type]}] route]
[[path (+ num keylen)] {:uri (str string-path uri)
:args (vec (concat path-keys args))
:type type}])
(into {})))]
(vary-meta `(vary-meta (compojure.core/context ~path ~args ~@routes)
assoc ::routes ~routes-map)
assoc ::routes routes-map)))
(defmacro register-route [route-name [type path args & body :as route]]
(let [string-path (if (vector? path) (first path) path)
route-args (:keys (clout.core/route-compile string-path))
route-id [route-name (count route-args)]
routes-map {route-id {:uri string-path
:type (keyword (string/lower-case (name type)))
:args (vec route-args)}}]
(vary-meta `(vary-meta ~route assoc ::routes ~routes-map)
assoc ::routes routes-map)))
(defn url-for [route & arg-values]
(let [{:keys [uri type args]} (get *reverse-routes* [route (count arg-values)])
root-path *root*]
(assert uri)
(str root-path
(reduce (fn [string [name val]]
(clojure.string/replace string (str name) (str val)))
uri (map vector args arg-values)))))
|