Skip to content

Instantly share code, notes, and snippets.

@rickmode
Created October 28, 2010 19:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rickmode/652096 to your computer and use it in GitHub Desktop.
Save rickmode/652096 to your computer and use it in GitHub Desktop.
;; this is a code fragement - it is missing necessary use / require
;; as well as dependent functions like do-validation and validation-errors
(defn form-action
"Build form action function for forms with validation.
success-fn is called with current request if validation succeeds.
failure-fn is called with current request (containing errors)
if validation fails.
(Though using this with no validators works, actions without validation
always call success-fn and so do not require this logic.)"
[success-fn failure-fn & validators]
(fn [request]
(let [request (do-validation request validators)]
(if (validation-errors request)
(failure-fn request)
(success-fn request)))))
(defmacro defformaction
"Defines a form action.
The name may be optionally be followed by a doc-string and metadata map.
Example:
(defformaction do-update-stuff
\"Updates stuff\"
(fn success [{{id :id field1 :field1 field2 :field2} :form-params :as request}]
; stateful persisting side-effect
(update-stuff id field1 field2)
; redirect to this object's page
(-> (redirect (str \"/stuff/\" id))
(add-flash-message \"Stuff updated\")))
(fn failure [request]
(stuff-form request)) ; redisplay stuff form with errors
; validation
(valid-required :id)
(valid-required :field1)
(valid-required :field2))"
[name success-fn failure-fn & validators]
(let [all-args (cons success-fn (cons failure-fn validators))
[name all-args] (name-with-attributes name all-args)
success-fn (first all-args)
failure-fn (second all-args)
validators (nnext all-args)]
`(def ~name
(form-action ~success-fn ~failure-fn ~@validators))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment