Skip to content

Instantly share code, notes, and snippets.

@sritchie
Created February 10, 2015 00:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sritchie/58cfe2af1325a1e6412d to your computer and use it in GitHub Desktop.
Save sritchie/58cfe2af1325a1e6412d to your computer and use it in GitHub Desktop.
;; ## State Methods
(defmulti initial-state
"Multimethod that returns the initial state for the supplied
page." :name)
(s/defmethod initial-state :default [r :- Route s :- (s/maybe AppState)] {})
(defmulti page-title
"Returns the current page title for the supplied route." :name)
(s/defmethod page-title :default [r :- Route] "")
(s/defn title :- s/Str
"Returns the supplied page's title."
[r :- Route]
(if-let [s (not-empty (page-title r))]
(str s " | RaceHub")
"RaceHub"))
#+clj
(do
(defmulti state
"Returns the server-side state for a particular resource. Accepts
the current route, the initial page state and the associated ring
request. Bounces the initial page state back by default."
(fn [route init-state req] (:name route)))
(s/defmethod state :default
[r :- Route init-state :- PageState req :- {s/Any s/Any}]
init-state))
(defn try-call
"If the supplied first argument is a function, applies it to the
supplied args. Else, returns f."
[f & args]
(if #+clj (or (fn? f) (instance? clojure.lang.MultiFn f))
#+cljs (fn? f)
(apply f args)
f))
#+clj
(do
(defmacro defroute
"Defines a route, with proper separation between clj and cljs. The
state function only gets expanded out in Clojure."
[k {:keys [initial-state state title]}]
`(do ~(when initial-state
`(s/defmethod initial-state ~k
[r# :- Route
current-state# :- (s/maybe AppState)]
(try-call ~initial-state r# current-state#)))
~(when state
`(u/when-clj
(s/defmethod state ~k
[r# :- Route
init-state# :- PageState
req# :- {s/Any s/Any}]
(try-call ~state r# init-state# req#))))
~(when title
`(s/defmethod page-title ~k
[r# :- Route]
(try-call ~title r#)))))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment