2008/09/15

[Common Lisp] Web フレームワークを作る。validation

validation くらいは必要かな。

まず普通の関数だった各ページ表示関数をメソッドにする。そこに :around でバリデーションをかぶせる。

(defmacro defaction (name (&rest options) &body body)
"options は権限的な何かに使えそう。"
(declare (ignore options))
`(progn
(setf (get ',name :action) t)
(defmethod ,name ()
,@body)))

(defmacro defvalidation (name (&key error-action) &body body)
`(defmethod ,name :around ()
(let ((*error-messages*
(remove nil
(list ,@(mapcar (lambda (form)
`(apply ',(second form)
(hunchentoot:parameter
,(>html (first form)))
(list ,@(cddr form))))
body)))))
(if *error-messages*
(,error-action)
(call-next-method)))))

(defun required (value &key (message "入力してください。"))
(if (emptyp value)
message))

というかんじで

(defaction arc1 ()
(html (:body
(error-messages)
(:form :action :arc2
(:input :type :text :name :foo)
(:input :type :submit)))))

(defaction arc2 ()
(html (:body (:a :href (>url :arc3 :foo @foo) "ここよ"))))

(defvalidation arc2 (:error-action arc1)
(foo required :message "foo を入力してください。"))

(defaction arc3 ()
(html (:body #"""you said: "#,@foo""""
(:br)
(:a :href 'arc1 '戻る))))

うむ、どうかな。。。

0 件のコメント: