Something that was bugging me for a while now, was that I couldn't figure out how to put if statements inside with-html expressions. (with-html is the Weblocks wrapper around with-html-output.) When I would try to just stick the if statement in there, the compiler would tell me things like "undefined function: :H2". I ended up doing what I consider pretty much the worst thing to do while programming, and copying and pasting a whole thing of code, and only changing parts of it, having two separate versions of a big long with-html expression depending on whether a certain variable was passed.
To do what I'm trying to do now, I needed it to depend on another variable, and having more than two huge copied and pasted sections was too ridiculous even for me. I tried a bunch of things, googled a lot, and had just finished drafting a post to the Weblocks group asking for help, when I decided to try actually reading the cl-who documentation. In retrospect, it seems obvious that I should have tried that a lot sooner.
I found this helpful piece of example code:
(with-html-output (*http-stream*)
(:h4 "Look at the character entities generated by this example")
(loop for i from 0
for string in '("Fête" "Sørensen" "naïve" "Hühner" "Straße")
do (htm
(:p :style (conc "background-color:" (case (mod i 3)
((0) "red")
((1) "orange")
((2) "blue")))
(htm (esc string))))))
Clearly, all I needed to do to make my if statements work, was enclose the with-html code in htm (actually cl-who:htm)! Here's what I ended up with, which is still not entirely refactored, and therefore still has some unfortunate code duplication:
(with-html
(:div :class "proposals-table-bg-back"
(:div :class "proposals-table-bg-thermometer"
:style (str (format nil "width: ~f%"
(let ((width (* 100
(/ (proposal-total-pledges item)
(proposal-target-amount item)))))
(if (> width 100)
100
(if (and (< width 1)
(not (= (proposal-total-pledges item) 0)))
1
width))))))
(:div :class "proposals-table-bg-thermometer-addon"))
(:table :class "proposals-table"
(:tr
(if (and (not ignoremini) (proposals-viewer-minip widget))
'() ;;okay this is dumb will change
(cl-who:htm (:td :rowspan 2 :class "proposal-amount"
(:h2 :class "proposal-current-amount"
(str (format nil "$~2$" (proposal-total-pledges item))))
(:h2 :class "proposal-of" "of")
(:h2 :class "proposal-target-amount"
(str (format nil "$~2$" (proposal-target-amount item)))))))
(:td :class "proposal-title"
(:h2 (render-link
(lambda (&rest args)
(declare (ignore args))
(do-page (make-proposal-page item)))
(humanize-name item-title)))
(if (and (not ignoremini) (proposals-viewer-minip widget))
'() ;;same here
(cl-who:htm (:td :class "proposal-pledge-form"
(render-widget pledge-widget))))))
(:tr
(if (and (not ignoremini) (proposals-viewer-minip widget))
(cl-who:htm (:td :class "proposal-amount"
(str (format nil "$~2$ / $~2$"
(proposal-total-pledges item)
(proposal-target-amount item)))))
(cl-who:htm (:td :colspan 2 :class "proposal-body"
(str (proposal-body item)))))))