CL-WHO 在有条件后不显示任何 HTML

CL-WHO not displaying any HTML after conditional

对于这个可能很愚蠢的问题,我深表歉意,但我是 Common Lisp 的新手(我是从 Racket 迁移过来的),到目前为止,我正在使用 Hunchentoot 构建 Web 应用程序,cl-who,并且其他一些杂项包,但我最近 运行 遇到了一个我无法解决的问题:我正在尝试遍历哈希并在哈希不为空时显示其值(结构)。如果是,我想显示 "this is empty" 消息。但是,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"))))) 

所以在这种情况下,"Create New Board" 出现了,但粗体文本和 header 都没有出现。但是,如果我在 if 之后移动 header,它就会出现。

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

Return 一个字符串

来自 http://weitz.de/hunchentoot:

Request handlers do their work by modifying the reply object if necessary and by eventually returning the response body in the form of a string or a binary sequence.

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

As an alternative, they can also call SEND-HEADERS and write directly to a stream.

使用hash-table-count

你正在使用 hash-table-size instead of hash-table-count,这意味着如果你有一个空的 table,大小(即容量)是正数但你没有显示任何东西,因为 dolist 没有做任何事情。顺便说一下,您还可以使用 maphashloop:

遍历 hash-tables
(maphash (lambda (key board)
           (declare (ignore key))
           (htm ...)) 
         *boards*)

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

1. 您没有看到任何 write 语句,但它们是由宏发出的。你可以 macroexpand forms yourself, or use Slime to do it quickly.