Common lisp Hunchentoot/cl who页面组成
Hunchentoot/cl who页面组成 我试着在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 "~@[~A - ~]Test Site" title))) (:body ,@body))))Common lisp Hunchentoot/cl who页面组成,common-lisp,hunchentoot,Common Lisp,Hunchentoot,Hunchentoot/cl who页面组成 我试着在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/
请注意,删除了
dolist
的mapcar
(我是一个策划人,不要让我太难喜欢lambdas,但它们在这里不是正确的选择),以及使用htm
来转义html s-exp(h-exps?)块。否则,对于带有html输出的,就不会有这样的上下文。最后,我必须在(str)
中包装文本,而不是:href
属性,以使它们能够动态展开。将html输出为字符串的宏使用。特别是,任何未识别的表单都保持原样,这意味着在生成html生成代码之前宏不会展开,这意味着当标准编译器展开publish newsfeed
宏时,它不再处于的上下文中,html输出为string
。在展开宏时,尤其是使用slime macroexpansion功能时,这一点很明显
要使其正常工作,您应该将publish newsfeed
设置为一个函数,并将与html输出一起使用,并将其与相同的流一起使用(假设“到处都有标准输出”或显式传递流)
(define-easy-handler (test-page :uri "/") ()
(page-template (:title "Splash Page") (:p "Testing testing")))
(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))))))))
(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")))))))))))))