diff --git a/modules/reitit-core/src/reitit/core.cljc b/modules/reitit-core/src/reitit/core.cljc index a582badb..5abf657d 100644 --- a/modules/reitit-core/src/reitit/core.cljc +++ b/modules/reitit-core/src/reitit/core.cljc @@ -334,13 +334,15 @@ ;; Creating Routers ;; + (defn ^:no-doc default-router-options [] {:lookup (fn lookup [[_ {:keys [name]}] _] (if name #{name})) :expand expand :coerce (fn coerce [route _] route) :compile (fn compile [[_ {:keys [handler]}] _] handler) :exception exception/exception - :conflicts (fn throw! [conflicts] (exception/fail! :path-conflicts conflicts))}) + :conflicts (fn throw! [conflicts] (exception/fail! :path-conflicts conflicts)) + :endpoint impl/leaf-endpoint}) (defn router "Create a [[Router]] from raw route data and optionally an options map. @@ -360,7 +362,10 @@ | `:validate` | Function of `routes opts => ()` to validate route (data) via side-effects | `:conflicts` | Function of `{route #{route}} => ()` to handle conflicting routes | `:exception` | Function of `Exception => Exception ` to handle creation time exceptions (default `reitit.exception/exception`) - | `:router` | Function of `routes opts => router` to override the actual router implementation" + | `:router` | Function of `routes opts => router` to override the actual router implementation + | `:endpoint` | Function of `prev-path path expanded-data data children => {:endpoint :inherit}`. + | | Used to transform data for this endpoint and data inherited to child routes. + | | Return falsy or `{:endpoint nil}` to skip path as endpoint and pass data to children." ([raw-routes] (router raw-routes {})) ([raw-routes opts] diff --git a/modules/reitit-core/src/reitit/impl.cljc b/modules/reitit-core/src/reitit/impl.cljc index c99d593b..8d8acaa6 100644 --- a/modules/reitit-core/src/reitit/impl.cljc +++ b/modules/reitit-core/src/reitit/impl.cljc @@ -37,7 +37,7 @@ coll coll)) -(defn walk [raw-routes {:keys [path data routes expand] +(defn walk [raw-routes {:keys [path data routes expand endpoint] :or {data [], routes []} :as opts}] (letfn @@ -53,10 +53,15 @@ (sequential? (first maybe-arg))) (nil? maybe-arg)) [{} args] - [maybe-arg (rest args)]) - macc (into macc (expand data opts)) - child-routes (walk-many (str pacc path) macc (keep identity childs))] - (if (seq childs) (seq child-routes) [[(str pacc path) macc]])))))] + [maybe-arg (rest args)])] + (let [d (endpoint pacc path macc data childs) + data-for-endpoint (when (:endpoint d) (into macc (expand (:endpoint d) opts))) + data-for-children (or (:inherit d) data) + macc (into macc (expand data-for-children opts))] + (-> (when data-for-endpoint [[(str pacc path) data-for-endpoint]]) + (concat (when (seq childs) (-> (str pacc path) + (walk-many macc (keep identity childs)) + (seq))))))))))] (walk-one path (mapv identity data) raw-routes))) (defn map-data [f routes] @@ -254,6 +259,12 @@ (query-parameter k v)))) (str/join "&"))) +(defn leaf-endpoint + [_ _ _ data childs] + (when-not (seq childs) + {:endpoint data + :inherit {}})) + (defmacro goog-extend [type base-type ctor & methods] `(do (def ~type (fn ~@ctor))