diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/reverse_routing/core.clj | 50 | 
1 files changed, 26 insertions, 24 deletions
diff --git a/src/reverse_routing/core.clj b/src/reverse_routing/core.clj index 4299eba..1977b2a 100644 --- a/src/reverse_routing/core.clj +++ b/src/reverse_routing/core.clj @@ -6,17 +6,17 @@  (def ^:private ^:dynamic *lookup-route* nil)  (def ^:private ^:dynamic *root* nil) +(defn ^:private deref-if-var [arg] +  (if (var? arg) +    (deref arg) +    arg)) +  (defn wrap-reverse-routing [handler & {:keys [root] :or {:root ""}}]    (fn [request]      (binding [*lookup-route* (->> handler deref-if-var meta ::lookup)                *root* root]        (handler request)))) -(defn ^:private deref-if-var [arg] -  (if (var? arg) -    (deref arg) -    arg)) -  (defn ^:private lookup-route [route & handlers]    (->> handlers         (map (comp ::lookup meta deref-if-var)) @@ -33,7 +33,7 @@    `(let ~bindings (routes ~@handlers)))  (defmacro when-routes [cond & handlers] -  `(when ~cond (routes ~@handlers))) +  `(if ~cond (routes ~@handlers) (routes)))  (defmacro defroutes [name & handlers]    `(def ~name (routes ~@handlers))) @@ -42,15 +42,16 @@    (let [string-path (if (vector? path) (first path) path)          path-keys (vec (:keys (clout.core/route-compile string-path)))          keylen (count path-keys) -        lookup-fn `(fn [[route-name# args-count#]] -                     (let [~args (repeat nil) ;; hacky, but necessary - provide nil values for args -                           r# (#'lookup-route [route-name# (- args-count# ~keylen)] -                                              ~@routes) -                           {uri# :uri, args# :args} r#] -                       (if r# -                         (assoc r# -                           :uri (str ~string-path uri#) -                           :args (vec (concat ~path-keys args#))))))] +        lookup-fn `(fn [[route-name# args#]] +                     (if (>= (count args#) ~keylen) +                       (let [~args args#  +                             r# (#'lookup-route [route-name# (vec (drop ~keylen args#))] +                                                ~@routes) +                             {uri# :uri, args# :args} r#] +                         (if r# +                           (assoc r# +                             :uri (str ~string-path uri#) +                             :args (vec (concat ~path-keys args#)))))))]      `(vary-meta (compojure.core/context ~path ~args                    (routes ~@routes))                  assoc ::lookup ~lookup-fn))) @@ -58,20 +59,21 @@  (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 {:uri string-path                      :type (keyword (string/lower-case (name type)))                      :args (vec route-args)}]      `(vary-meta ~route -                assoc ::lookup (fn [signature#] -                                 (if (= signature# ~route-id) +                assoc ::lookup (fn [[name# args#]] +                                 (if (and (= name# ~route-name) +                                          (= (count args#) (count ~(vec route-args))))                                     ~routes-map)))))  (defn url-for [route & arg-values] -  (let [{:keys [uri type args]} (*lookup-route* [route (count arg-values)]) +  (let [spec (*lookup-route* [route arg-values]) +        {:keys [uri type args]} spec          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))))) +    (if spec +      (str root-path +           (reduce (fn [string [name val]] +                     (clojure.string/replace string (str name) (str val))) +                   uri (map vector args arg-values))))))  | 
