[cl-who-devel] Building a table from a list of strings - Can't seem to get it right

Looking at the checkerboard-like example in the docs and trying to figure out how to get a table from a list of strings. Assume a list of 50 strings and I want to get them into a table that is 5 cells wide and 10 high. I can't seem to get the loop(s) right with the rows. I can do this without cl-who, but there should be an obvious method that I'm missing to be able to do this with cl-who. I apparently don't know enough loop-fu. Any pointers would be appreciated. Bryan

Hi Bryan, cl-who does have limitations, and one of them I've found is that it works best if you know a priori the structure you're generating. Putting items into a table in HTML, unfortunately, doesn't quite have this property. Still, you can certainly use it for that, especially if you don't mind nesting loops -- maybe something like: (defun gridify (x &optional (col 5)) "given a list of strings, put them in an html table (returned as a string) with |col| columns." (with-html-output-to-string (var nil) (:table (loop for xp on x by (lambda (p) (nthcdr col p)) do (htm (:tr (loop for i upto (1- col) for xi in xp do (htm (:td (str xi)))))))))) (gridify (loop for i from 1 upto 50 collect (format nil "cell #~D" i))) cheers, - Ken

Now I'm really confused. Ken's example does exactly what I want when I create a gridify function and call it from a page macro (defmacro templates at the bottom of the email). But if I put the function body into the page macro, (see second example), it doesn't work. Rather, it prints the entire table, complete with tr and td with no string - then drops the list of strings after the table Both use exactly the same macros to generate the page and it is a cut and paste job. Somehow putting the function body into the macro is changing how the loops work: WORKS (defun gridify (x &optional (col 5)) "given a list of strings, put them in an html table (returned as a string) with |col| columns." (with-html-output-to-string (var nil) (:table (loop for xp on x by (lambda (p) (nthcdr col p)) do (htm (:tr (loop for i upto (1- col) for (id name) in xp do (htm (:td (:a :href (format nil "~a~a" "countries-display?id=" id) (str name))))))))))) (defpage-easy-slp gridify-countries "Countries Grid" "/gridify-countries" () (let* ((data-query "select id,name from countries order by name ") (results (query data-query)) (col 5)) (gridify results col))) DOESNT WORK (defpage-easy-slp countries-grid "Countries Grid" "/countries-grid" () (let* ((data-query "select id,name from countries order by name ") (x (query data-query)) (col 5)) (with-html-output-to-string (var nil) (:table (loop for xp on x by (lambda (p) (nthcdr col p)) do (htm (:tr (loop for i upto (1- col) for (id name) in xp do (htm (:td (:a :href (format nil "~a~a" "countries-display?id=" id) (str name)))))))))))) DEF MACROS (defmacro page-template (title &body body) `(with-html-output-to-string (*standard-output* nil :prologue t :indent t) (:html (:head (:link :rel "stylesheet" :type "text/css" :href "/css/screen.css" :media "screen") (:title (str (format nil " ~a" ,title)))) (:body (:div :class "container" (:div :class "column span-24" (str ,@body)))))))) (defmacro defpage-easy-slp (name title uri parameter-list &body body) `(define-easy-handler (,name :uri ,uri :default-request-type :both) ,parameter-list (page-template ,title ,@body)))

Bryan Emrys schrieb:
Now I'm really confused. Ken's example does exactly what I want when I create a gridify function and call it from a page macro (defmacro templates at the bottom of the email). But if I put the function body into the page macro, (see second example), it doesn't work. Rather, it prints the entire table, complete with tr and td with no string - then drops the list of strings after the table Both use exactly the same macros to generate the page and it is a cut and paste job. Somehow putting the function body into the macro is changing how the loops work:
WORKS (defun gridify (x &optional (col 5)) "given a list of strings, put them in an html table (returned as a string) with |col| columns." (with-html-output-to-string (var nil) (:table (loop for xp on x by (lambda (p) (nthcdr col p)) do (htm (:tr (loop for i upto (1- col) for (id name) in xp do (htm (:td (:a :href (format nil "~a~a" "countries-display?id=" id) (str name)))))))))))
(defpage-easy-slp gridify-countries "Countries Grid" "/gridify-countries" () (let* ((data-query "select id,name from countries order by name ") (results (query data-query)) (col 5)) (gridify results col)))
DOESNT WORK
(defpage-easy-slp countries-grid "Countries Grid" "/countries-grid" () (let* ((data-query "select id,name from countries order by name ") (x (query data-query)) (col 5)) (with-html-output-to-string (var nil) (:table (loop for xp on x by (lambda (p) (nthcdr col p)) do (htm (:tr (loop for i upto (1- col) for (id name) in xp do (htm (:td (:a :href (format nil "~a~a" "countries-display?id=" id) (str name))))))))))))
DEF MACROS
(defmacro page-template (title &body body) `(with-html-output-to-string (*standard-output* nil :prologue t :indent t) (:html (:head (:link :rel "stylesheet" :type "text/css" :href "/css/screen.css" :media "screen") (:title (str (format nil " ~a" ,title)))) (:body (:div :class "container" (:div :class "column span-24" (str ,@body))))))))
(defmacro defpage-easy-slp (name title uri parameter-list &body body) `(define-easy-handler (,name :uri ,uri :default-request-type :both) ,parameter-list (page-template ,title ,@body)))
see http://lisp-univ-etc.blogspot.com/2009/03/cl-who-macros.html Jens

Ahh. Dawn begins to break over Marblehead. Thank you all. Bryan On Wed, Jun 17, 2009 at 9:35 AM, Jens Teich <info@jensteich.de> wrote:
Now I'm really confused. Ken's example does exactly what I want when I create a gridify function and call it from a page macro (defmacro templates at the bottom of the email). But if I put the function body into the page macro, (see second example), it doesn't work. Rather, it prints the entire
Both use exactly the same macros to generate the page and it is a cut and
Bryan Emrys schrieb: table, complete with tr and td with no string - then drops the list of strings after the table paste job. Somehow putting the function body into the macro is changing how the loops work:
WORKS (defun gridify (x &optional (col 5)) "given a list of strings, put them in an html table (returned as a
string) with |col| columns."
(with-html-output-to-string (var nil) (:table (loop for xp on x by (lambda (p) (nthcdr col p)) do (htm (:tr (loop for i upto (1- col) for (id name) in xp do (htm (:td (:a :href (format nil "~a~a" "countries-display?id=" id) (str name)))))))))))
(defpage-easy-slp gridify-countries "Countries Grid" "/gridify-countries" () (let* ((data-query "select id,name from countries order by name ") (results (query data-query)) (col 5)) (gridify results col)))
DOESNT WORK
(defpage-easy-slp countries-grid "Countries Grid" "/countries-grid" () (let* ((data-query "select id,name from countries order by name ") (x (query data-query)) (col 5)) (with-html-output-to-string (var nil) (:table (loop for xp on x by (lambda (p) (nthcdr col p)) do (htm (:tr (loop for i upto (1- col) for (id name) in xp do (htm (:td (:a :href (format nil "~a~a" "countries-display?id=" id) (str name))))))))))))
DEF MACROS
(defmacro page-template (title &body body) `(with-html-output-to-string (*standard-output* nil :prologue t :indent t) (:html (:head (:link :rel "stylesheet" :type "text/css" :href "/css/screen.css" :media "screen") (:title (str (format nil " ~a" ,title)))) (:body (:div :class "container" (:div :class "column span-24" (str ,@body))))))))
(defmacro defpage-easy-slp (name title uri parameter-list &body body) `(define-easy-handler (,name :uri ,uri :default-request-type :both) ,parameter-list (page-template ,title ,@body)))
see http://lisp-univ-etc.blogspot.com/2009/03/cl-who-macros.html
Jens
_______________________________________________ cl-who-devel site list cl-who-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/cl-who-devel

Bryan Emrys wrote:
Looking at the checkerboard-like example in the docs and trying to figure out how to get a table from a list of strings. Assume a list of 50 strings and I want to get them into a table that is 5 cells wide and 10 high. I can't seem to get the loop(s) right with the rows. I can do this without cl-who, but there should be an obvious method that I'm missing to be able to do this with cl-who. I apparently don't know enough loop-fu.
Can you show your code and tell us what you're expecting it to do? Leslie -- http://www.linkedin.com/in/polzer
participants (4)
-
Bryan Emrys
-
Jens Teich
-
Ken Harris
-
Leslie P. Polzer