Discussion:
Building a table from a list of strings - Can't seem to get it right
Bryan Emrys
2009-06-16 03:32:10 UTC
Permalink
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
Ken Harris
2009-06-16 06:49:07 UTC
Permalink
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

_______________________________________________
cl-who-devel site list
cl-who-***@common-lisp.net
http://common-
Bryan Emrys
2009-06-17 05:53:45 UTC
Permalink
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)))
Jens Teich
2009-06-17 16:35:17 UTC
Permalink
Post by Bryan Emrys
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
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"
(defmacro defpage-easy-slp (name title uri parameter-list &body body)
`(define-easy-handler (,name :uri ,uri
:default-request-type :both)
,parameter-list
see http://lisp-univ-etc.blogspot.com/2009/03/cl-who-macros.html

Jens
Bryan Emrys
2009-06-17 17:30:37 UTC
Permalink
Ahh. Dawn begins to break over Marblehead. Thank you all.

Bryan
Post by Bryan Emrys
Post by Bryan Emrys
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
Post by Bryan Emrys
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
Post by Bryan Emrys
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."
Post by Bryan Emrys
(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)))))))))))
Post by Bryan Emrys
(defpage-easy-slp gridify-countries "Countries Grid" "/gridify-countries"
()
Post by Bryan Emrys
(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))))))))))))
Post by Bryan Emrys
DEF MACROS
(defmacro page-template (title &body body)
`(with-html-output-to-string (*standard-output* nil :prologue t
:indent t)
Post by Bryan Emrys
(:html
(:head
(:link :rel "stylesheet" :type "text/css" :href "/css/screen.css"
:media "screen")
Post by Bryan Emrys
(:title (str (format nil " ~a" ,title))))
(:body
(:div :class "container"
(:div :class "column span-24"
(defmacro defpage-easy-slp (name title uri parameter-list &body body)
`(define-easy-handler (,name :uri ,uri
:default-request-type :both)
,parameter-list
see http://lisp-univ-etc.blogspot.com/2009/03/cl-who-macros.html
Jens
_______________________________________________
cl-who-devel site list
http://common-lisp.net/mailman/listinfo/cl-who-devel
Leslie P. Polzer
2009-06-16 08:15:38 UTC
Permalink
Post by Bryan Emrys
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
Loading...