2008/09/16

[Common Lisp] Web フレームワークを作る。テンプレート

Struts の tiles みたいなイメージのテンプレートを実装しようかと思った。でも S 式で HTML 出力するから、わざわざテンプレートの仕組みを実装する必要なんかなくって、マクロを1つ定義してしまえばおしまい。

こんな感じ。

(defmacro default-template ((&key (title "Arc Challenge")) &body body)
`(html (:head (:title ,title))
(:body ,@body)))

(defaction arc1 ()
(default-template ()
(error-messages)
(:form :action :arc2
"foo: " (:input :type :text :name :foo)
(:input :type :submit))))

上の arc1 を適当にマクロ展開(Slime で C-c C-m)すると次のようになる。すごくべただ。

(PROGN
(SETF (GET 'ARC1 :ACTION) T)
(DEFMETHOD ARC1 NIL
(PROGN
(PROGN
(PRINC "<")
(PRINC "head")
(PRINC ">")
(PROGN
(PROGN
(PRINC "<")
(PRINC "title")
(PRINC ">")
(PROGN (PRINC (>HTML "Arc Challenge")) (VALUES))
(PRINC "</")
(PRINC "title")
(PRINC ">"))
(VALUES))
(PRINC "</")
(PRINC "head")
(PRINC ">"))
(PROGN
(PRINC "<")
(PRINC "body")
(PRINC ">")
(PROGN (PRINC (>HTML (ERROR-MESSAGES))) (VALUES))
(PROGN
(PROGN
(PRINC "<")
(PRINC "form")
(FORMAT T " ~a=\"~a\"" "action" (>HTML :ARC2))
(PRINC ">")
(PROGN (PRINC (>HTML "foo: ")) (VALUES))
(PROGN
(PROGN
(PRINC "<")
(PRINC "input")
(FORMAT T " ~a=\"~a\"" "type" (>HTML :TEXT))
(FORMAT T " ~a=\"~a\"" "name" (>HTML :FOO))
(PRINC "/>"))
(VALUES))
(PROGN
(PROGN
(PRINC "<")
(PRINC "input")
(FORMAT T " ~a=\"~a\"" "type" (>HTML :SUBMIT))
(PRINC "/>"))
(VALUES))
(PRINC "</")
(PRINC "form")
(PRINC ">"))
(VALUES))
(PRINC "</")
(PRINC "body")
(PRINC ">"))
(VALUES))))

0 件のコメント: