[cl-who-devel] When tagname/attributes can be determined only at runtime (WITH-HTML-TAG)

Chaitanya Gupta mail at chaitanyagupta.com
Sun May 25 07:23:09 UTC 2008


Hi,

While using CL-WHO recently, I ran into a small problem wherein some 
tagnames/attributes could be determined only at runtime. Not knowing any 
easy way to do this "out of the box" in CL-WHO, I wrote this small macro 
(inspired by XML-EMITTER:WITH-TAG) -


(defmacro with-html-tag ((name &optional attributes) &body body)
  (let ((body-fn (gensym)))
    `(flet ((,body-fn () , at body))
       (call-with-html-tag ,name ,attributes #',body-fn))))


(defun call-with-html-tag (name attributes body-fn)
  (let ((tag-name (typecase name
                    (symbol (string-downcase name))
                    (t name))))

    (format t "<~A" tag-name)
    (when attributes
      (format t "~{~A~}" (cl-who:convert-attributes attributes)))
    (format t ">")
    (funcall body-fn)
    (format t "</~A>" tag-name)))


Note that it writes only to *standard-output*.

Usage
-----

(defvar *x* :blockquote) => *X*


(with-output-to-string (*standard-output*)
  (cl-who:with-html-output (*standard-output*)
    (:body
     (with-html-tag (*x*)
       (cl-who:htm (:p "foo bar"))))))
=>
"<body><blockquote><p>foo bar</p></blockquote></body>"


(with-output-to-string (*standard-output*)
  (cl-who:with-html-output (*standard-output*)
    (:body
     (with-html-tag (*x* '(("id" . "foo123")))
       (cl-who:htm (:p "foo bar"))))))
=>
"<body><blockquote id='foo123'><p>foo bar</p></blockquote></body>"



I think this will be a useful addition to CL-WHO (although this 
particular implementation can be improved a bit). Or did I miss out on 
some other way that CL-WHO can easily handle this?

Chaitanya






More information about the Cl-who-devel mailing list