Hunchentoot/CL-誰頁面構成Hunchentoot/CL-誰頁組合
我試圖拼湊幾頁中hunchentoot作爲一個實驗,我快到一個意想不到的牆。作爲一個例子,我有以下模板宏。
(defmacro page-template ((&key title) &body body) `(with-html-output-to-string (*standard-output* nil :prologue t :indent t) (:html :xmlns "http://www.w3.org/1999/xhtml" :xml\:lang "en" :lang "en" (:head (:meta :http-equiv "Content-Type" :content "text/html;charset=utf-8") (:title ,(format nil "[email protected][~A - ~]Test Site" title))) (:body ,@body))))
現在,當我有一個純文本頁面,還是一個充滿了HTML文本像
(define-easy-handler (test-page :uri "/")() (page-template (:title "Splash Page") (:p "Testing testing")))
一切都OK。該頁面輸出正確,我可以立即看到我的代碼的努力。但是,當我有一個由冗餘元素組成的頁面時,並不那麼簡單。例如,假設我有一個頁面,無論出於何種原因,我想顯示三個RSS新聞傳遞。這是一個足夠複雜的成分,我想它抽象出來,所以我minnd,我應該能夠做到像
(define-easy-handler (test-feed :uri "/feeds")() (page-template (:title "Splash Page") (publish-newsfeed "http://nf-one.html") (publish-newsfeed "http://nf-two.html") (publish-newsfeed "http://nf-three.html"))) (defmacro publish-newsfeed (url &optional (item-limit 5)) (flet ((get-text (s-tree node-path) (car (last (xmls-tools:find-subtree s-tree node-path))))) (let ((rss-feed (xmls:parse (drakma:http-request url)))) `(:div :class "rss-feed" (:a :href ,(get-text rss-feed '("channel" "link")) :target "_top" (:h1 ,(get-text rss-feed '("channel" "title")))) (:ul ,@(mapcar #'(lambda (item) `(:li (:a :href ,(get-text item '("link")) :target "_top" (:h2 ,(get-text item '("title")))) (:p :class "date" ,(get-text item '("pubDate"))) (:p ,(get-text item '("description"))))) (let ((items (xmls-tools:find-all-children (xmls-tools:find-subtree rss-feed '("channel")) "item"))) (if (> (length items) item-limit) (subseq items 0 item-limit) items))))))))
但上述結果是「服務器錯誤」頁面。我不確定爲什麼; page-template
是一個宏,因此publish-newsfeed
的調用只有在with-html-output-to-string
的情況下才能擴展。誰能告訴我我做錯了什麼?
此外,仔細檢查各種Hunchentoot/cl-誰教程,他們似乎沒有一個這樣的頁面組成。具有Hunchentoot經驗的任何人都可以告訴我,將頁面分解爲組件的正確/規範方法是什麼?
編輯:
通過下面Ramarren正確響應; with-html-output
宏在不同的評估規則下工作。發佈 - 新聞推送的是實際上在這種情況下工作的版本實際上是
(defun publish-newsfeed (url &optional (item-limit 5)) (flet ((get-text (s-tree node-path) (car (last (xmls-tools:find-subtree s-tree node-path))))) (let* ((rss-feed (xmls:parse (drakma:http-request url))) (items (xmls-tools:find-all-children (xmls-tools:find-subtree rss-feed '("channel")) "item")) (ltd-items (if (> (length items) item-limit) (subseq items 0 item-limit) items))) (with-html-output (*standard-output* nil :indent t) (:div :class "rss-feed" (:a :href (get-text rss-feed '("channel" "link")) :target "_top" (:h1 (str (get-text rss-feed '("channel" "title"))))) (:ul (dolist (item ltd-items) (htm (:li (:h2 (:a :href (get-text item '("link")) :target "_top" (str (get-text item '("title"))))) (:p :class "date" (str (get-text item '("pubDate")))) (:p (str (get-text item '("description")))))))))))))
注意去除mapcar
爲dolist
(我是一個陰謀家,不要給我太多的困難時期大約喜歡lambda表達式,但他們不是這裏的正確選擇),並且使用htm
來轉義不會在with-html-output
上下文中的html s-exps(h-exps?)塊。最後,我必須包裝文字,但不要(str)
中的:href
屬性使它們動態擴展。