for loop in XHTML

248 views
Skip to first unread message

Oliver

unread,
Aug 27, 2008, 8:57:05 PM8/27/08
to lif...@googlegroups.com
A JSP has a for loop but I can't remember seeing any in Lifts tags.

How do I output multiple rows of a similar HTML fragment in Lift?

Alexander Kosenkov

unread,
Aug 28, 2008, 5:39:39 AM8/28/08
to liftweb
> A JSP has a for loop but I can't remember seeing any in Lifts tags.

Lift does not use tags for output control (programming).
You should do all your output in the code.
For example, you can map List of entries to their html presentation
and output the result.

You can check Hello Darvin sample application for example

Marius

unread,
Aug 28, 2008, 8:12:33 AM8/28/08
to liftweb
Snippets can be used for such purposes. For instance:

class HelloWorld {
def loop(xhtml: Group) : NodeSeq = {
val list = "one" :: "two" :: "three" :: Nil

list flatMap (elem => bind("test", xhtml, "value" --> Text(elem)))
}

}

and in your page:

<lift:HelloWorld.loop>
<div>
<test:value />
</div>
</lift:HelloWorld.loop>



Br's,
Marius

Oliver Lambert

unread,
Aug 28, 2008, 8:24:03 AM8/28/08
to lif...@googlegroups.com
First, thanks for your response.

Lift doesn't use tags - Ok. I've read the Hello Darwin examples and
they don't answer my question - they are pretty thin examples.
I can see I can generate a drop down list - that good.
I can see I can generate html - thats good.

However, I want my html to be stored in a format that is changeable
outside of Scala. So it's stored as a html file as is the fragment
of html (not simply a text field or a pop list) I want to repeat.
This means that I need to read it into Scala, manipulate it and output
the the modified html.

I've read the Hello Darwin example an

Oliver Lambert

unread,
Aug 28, 2008, 8:30:51 AM8/28/08
to lif...@googlegroups.com
Can Text(elem) be arbitrary html representing a row with multiple Text
fields?

David Pollak

unread,
Aug 28, 2008, 9:04:57 AM8/28/08
to lif...@googlegroups.com


Oliver Lambert wrote:
Can Text(elem) be arbitrary html representing a row with multiple Text  
fields?

  
Yes.  the right hand side of '-->' is a scala.xml.NodeSeq so it can be arbitrary XHTML.

David Pollak

unread,
Aug 28, 2008, 1:02:19 PM8/28/08
to lif...@googlegroups.com
Oliver,

I've put together a complex example of templating with Lift.

All the code is in sites/examples... but here goes.

The html file looks like:
<lift:surround with="default" at="content">
 <lift:Template.show template="_simple_template" />
</lift:surround>

The template file contains two templates... a "tbl" template and a "row" template:

<temp:main>
  <temp:tbl>
    <table>
      <tr>
    <td><head:one/></td>
    <td><head:two/></td>
      </tr>
      <head:rows />
    </table>
  </temp:tbl>
 
  <temp:row>
    <tr>
      <td><item:one/></td>
      <td><item:two/></td>
    </tr>
  </temp:row>
 
</temp:main>

It is placed in the webapps/_simple_template.html file.  This file is referenced in the "template" attribute.  You could put it in "/templates-hidden/my_fancy_template.html" and make sure that the "template" attribute in your <lift:Template.show /> tag refers to that path.  Note also, that Lift's entire template loading mechanism is used... so localization will be used, etc.

This invokes the "show" method in the Template snippet.  This code looks like:

  def show(in: NodeSeq): NodeSeq = {
    val ret: Can[NodeSeq] =
      for (tmpl <- templateFromTemplateAttr; // Load the template
       // parse out the "tbl" and "row" subtemplates
       (tbl, row) <- template(tmpl, "temp", "tbl", "row"))
    yield {
         // iterate over the users in the DB and bind each to a row
         val rows: NodeSeq =
           User.findAll match {
         case Nil => bind("item", row, "one" -> "No Records Found",
                  "two" -> "")
         case xs => xs.flatMap(u => bind("item", row,
                         "one" -> u.firstName.is,
                         "two" -> u.email.is))
           }
     
      // bind the rows and the names of the rows to the "tbl" template
      bind("head", tbl, "one" -> "Name",
           "two" -> "Email",
           "rows" -> rows)
    }
   
        // be graceful on failures
    ret match {
      case Full(xs) => xs
      case Empty => Text("Error processing template")
      case Failure(msg, _, _) => Text("Error processing template: "+msg)
    }
  }


I hope this helps.

Thanks,

David
--
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp

Oliver

unread,
Aug 29, 2008, 12:06:06 AM8/29/08
to lif...@googlegroups.com
David,

This helps - Thankyou

cheers
Oliver
Reply all
Reply to author
Forward
0 new messages