CL-WHO не отображает HTML после условного

Извините за, возможно, глупый вопрос, но я новичок в Common Lisp (я мигрировал из Racket), и до сих пор у меня полный успех, когда я создаю веб-приложение с Hunchentoot, cl-who и несколькими другими разными пакетами, но Недавно я столкнулся с проблемой, которую не могу решить: я пытаюсь перебрать хеш и показать его значения (которые являются структурами), если хеш не пустой. Если это так, я хочу отобразить сообщение "это пусто". Однако 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, он появляется.

Я боролся с этим более шести часов, у кого-нибудь есть намеки на меня? Спасибо!

1 ответ

Решение

Вернуть строку

С 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 или же 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, чтобы сделать это быстро.

Другие вопросы по тегам