Sorry for the probably stupid question, but I'm new to Common Lisp (I migrated from Racket) and so far I'm having an absolute blast building a web app with Hunchentoot, cl-who, and a few other miscellaneous packages, but I've recently run into an issue I can't solve: I'm trying to loop through a hash and display its values (which are structs) if the hash is not empty. If it is, I want to display an "this is empty" message. However, cl-who is only outputting the HTML that comes after the call. Here is my code:
(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")))))
So in this case, "Create New Board" is showing up, but neither the bold text nor the header are. However, if I move the header after the if, it shows up.
I've struggled with this for upwards of six hours, does anyone have any hints for me? Thanks!
Return a string
From http://weitz.de/hunchentoot:
The handler should return a string and here the only thing that is emitted is the last value being printed (because
writereturns its argument)1. That's why you only see the last element. You need to usewith-html-output-to-string; generally you add a variableoutin the binding, but in most cases that variable is not used (at least not here). You can use*standard-output*but you have to be careful. Better rebind*standard-output*in the smallest scope where it is useful. It is possible to use the stream associated with the current response, if you prefer not building a string first .Use
hash-table-countYou are using
hash-table-sizeinstead ofhash-table-count, which means that if you have an empty table, the size (i.e. the capacity) is positive but you don't show anything because the dolist doesn't do anything. By the way, you can also iterate over hash-tables withmaphashorloop:1. You don't see any
writestatement, but they are emitted by the macro. You canmacroexpandforms yourself, or use Slime to do it quickly.