cl-markupはcl-whoと挙動が違うので使うときは注意が必要。
(eval-when (:compile-toplevel :load-toplevel :execute) (require :clack) (require :cl-markup) (require :cl-ppcre) (require :drakma) ) (defpackage :sample-app (:use :cl :clack :clack.request :clack.app.route :clack.builder :clack.session.state.cookie :clack.middleware.session :cl-markup :cl-ppcre :drakma )) (in-package :sample-app) (defroutes sample-session-app (env) (GET "/" #'index) ; トップページ。 (GET "/getdata" #'getdata) ; GETによるデータ受け渡し (POST "/postdata" #'postdata) ; POSTによるデータ受け渡し (GET "/session" #'session)) ; sessionによるデータの受け渡し (defun index (env) "トップページを生成 最初にセッションに変数を代入している。" (setf (gethash :data1 (getf env :clack.session)) "データ1") (setf (gethash :data2 (getf env :clack.session)) "データ2") (setf (gethash :data3 (getf env :clack.session)) '("データ3-1" "データ3-2" "データ3-3")) `(200 (:content-type "text/html") (,(markup (html (:head (:meta :content "text/html" :charset "UTF-8") (:title "index")) (:body ;; GETデータを送信するフォーム (:form :method "get" :action "/getdata" "GET" (:input :type "text" :name "getname") (:input :type "submit")) ;; POSTデータを送信するフォーム (:form :method "post" :action "/postdata" "POST" (:input :type "text" :name "postname") (:input :type "submit")) (:br) ;; セッションデータを確認する画面へのリンク (:a :href "/session" "セッションテスト") )))))) (defun get-parameter (uri) "URIからGETデータを分離する適当な関数" (when (cl-ppcre:scan "\\?" uri) (let ((get-data (second (cl-ppcre:split "\\?" uri)))) (when get-data (mapcar #'(lambda (x) (cl-ppcre:split "\\=" x)) (cl-ppcre:split "\\&" get-data)))))) (defun getdata (env) "GETされたデータを表示する" `(200 (:content-type "text/html") (,(markup (html (:head (:meta :content "text/html" :charset "UTF-8") (:title "get")) (:body (loop for i in (get-parameter (getf env :request-uri)) collect (format nil "~a" (hunchentoot:url-decode (second i)))) )))))) (defun postdata (env) "POSTされたデータを表示する" (let ((req (make-request env))) `(200 (:content-type "text/html") (,(markup (html (:head (:meta :content "text/html" :charset "UTF-8") (:title "post")) (:body "post data: " (body-parameter req "postname")))))))) (defun session (env) "セッションデータを表示する" `(200 (:content-type "text/html") (,(markup (html (:head (:meta :content "text/html" :charset "UTF-8") (:title "session")) (:body (gethash :data1 (getf env :clack.session)) (:br) (gethash :data2 (getf env :clack.session)) (:br) (loop for i in (gethash :data3 (getf env :clack.session)) collect (markup (:span i (:br)))) )))))) ;; セッションを有効にしてClackを起動 (clackup (builder (<clack-middleware-session> :state (make-instance '<clack-session-state-cookie>)) #'sample-session-app))
SESSIONを有効にしてトップページにアクセスするとCookieが挿入されるようになる。
CL-USER> (drakma:http-request "http://localhost:5000") "<html><head><meta content=\"text/html\" charset=\"UTF-8\" /><title>test</title></head><body><form method=\"get\" action=\"/getdata\">GET<input type=\"text\" name=\"getname\" /><input type=\"submit\" /></form><form method=\"post\" action=\"/postdata\">POST<input type=\"text\" name=\"postname\" /><input type=\"submit\" /></form><br /><a href=\"/session\">セッションテスト</a></body></html>" 200 ((:CONTENT-LENGTH . "371") (:DATE . "Wed, 08 Jun 2011 22:08:11 GMT") (:SERVER . "Hunchentoot 1.1.1") (:CONNECTION . "Close") (:SET-COOKIE . "CLACK.SESSION=dd878a54b3570f7bb06236358ebe56194ff6b848; path=/; expires=Sat, 14 Nov 2122 18:59:08 GMT") (:CONTENT-TYPE . "text/html")) #<URI http://localhost:5000/> #<FLEXI-STREAMS:FLEXI-IO-STREAM #x2103B8F79D> T "OK"この状態でブラウザからlocalhost:5000へアクセスし、フォームに入力してSUBMITボタンを押せばデータの受け渡しが確認できる。
cl-markupはcl-whoとは使い勝手が違うのでちょっと注意が必要。loopで回して直接文字列を出力(タグを使わない)場合は以下みたいにする(のが正しいのかな?)
CL-USER> (markup (html (:body (loop for i in '(1 2 3 4 5) collect (format nil "~a<br />~%" i))))) "<html><body>1<br /> 2<br /> 3<br /> 4<br /> 5<br /> </body></html>"
1 件のコメント:
get-parameterは、Clack.Requestのquery-parameterで取れます
http://clacklisp.org/doc/clack.request.html
> cl-markupはcl-whoとは使い勝手が違うのでちょっと注意が必要。loopで回して直接文字列を出力(タグを使わない)場合は以下みたいにする(のが正しいのかな?)
正しいです。もし<br />をmarkupで書きたければ、
(loop for i in '(1 2 3 4 5)
collect (princ-to-string i)
collect (markup (:br)))
コメントを投稿