2

抱歉这个可能很愚蠢的问题,但我是 Common Lisp 的新手(我是从 Racket 迁移过来的),到目前为止,我正在用 Hunchentoot、cl-who 和其他一些杂项包构建一个 Web 应用程序,但是我最近遇到了一个我无法解决的问题:如果哈希不为空,我正在尝试遍历一个哈希并显示它的值(它们是结构)。如果是,我想显示“这是空的”消息。但是, cl-who 仅输出调用后的 HTML。这是我的代码:

(tbnl:define-easy-handler (index :uri "/") () 
  "Landing page." 
  (setf (tbnl:content-type*) "text/html") 
  (with-html-ouptut (*standard-output*) 
    (:html 
     (:head (:title "Chattr: Neo-BBS")) 
     (:body 
      (:div :id "header" 
            :style "text-align:center;" 
            (:h1 "Welcome to Chattr") 
            (:h3 "Please select the sub-board you would like to chat 
            on.")) 
      (if (> (hash-table-size *boards*) 0) 
          (dolist (board (hash-table-values *boards*)) 
            (htm 
             (:span (html-display board)) (:br)))
          (htm 
           (:b "Sorry, there aren't any boards. Why not create 
                one?") (:br))) 
      (:a :href "/new-board" "Create New Board"))))) 

所以在这种情况下,“创建新板”出现了,但粗体文本和标题都没有。但是,如果我在 if 之后移动标题,它就会显示出来。

我已经为此苦苦挣扎了六个多小时,有人对我有任何提示吗?谢谢!

4

1 回答 1

4

返回一个字符串

来自http://weitz.de/hunchentoot

请求处理程序通过在必要时修改回复对象并最终以字符串或二进制序列的形式返回响应主体来完成他们的工作。

处理程序应该返回一个字符串,这里唯一发出的是最后一个被打印的值(因为write返回它的参数)1。这就是为什么你只看到最后一个元素。你需要使用with-html-output-to-string; 通常,您out在绑定中添加一个变量,但在大多数情况下,该变量不被使用(至少在这里不使用)。你可以使用*standard-output*,但你必须小心。最好在有用的最小范围内重新绑定*standard-output*。如果您不想先构建字符串,则可以使用与当前响应关联的流。

作为替代方案,他们也可以调用 SEND-HEADERS 并直接写入流。

利用hash-table-count

您正在使用hash-table-size而不是hash-table-count,这意味着如果您有一个空表,则大小(即容量)为正,但您不显示任何内容,因为 dolist 不执行任何操作。maphash顺便说一句,您还可以使用or迭代哈希表 loop

(maphash (lambda (key board)
           (declare (ignore key))
           (htm ...)) 
         *boards*)

(loop
  for board being the hash-values of *boards*
  do (htm ...))

1.您看不到任何write语句,但它们是由宏发出的。你可以macroexpand自己形成,也可以使用 Slime快速完成。

于 2017-07-29T18:11:46.077 回答