Taking control of Lift’s snippet rendering

Posted by – September 26, 2009

One of the features that I always pay attention in a framework is how we can control what can be rendered in a view and what not, many frameworks uses a scriplet language, some others uses a kind of template system for this purpose and a few give to the user a object oriented way to do it.

In this article I’ll show an example of how we can take the control of view rendering on lift framework with the help of snippets. With snippets you will be able to perform any server side interaction that you need, you can call a snippet by placing a tag on view code, this tag has a naming convention required to call the snippet properly, a snippet always emmit markup back to the user.

This example will give to us a way to not show a html table when there’s no data available to the user, I could find something similar on Lift’s examples, but they don’t hide the table header there, my example doesn’t show the table at all and replace the table by a application message.

Please consider the following view/page that is used to list all registered suppliers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!--
We use this tag to specify which template
this view uses, Lift will merge all markup
defined here with template markup.
-->
<lift:surround with="list">

    <!--    
    We use the tag below to specify what will be inserted
    in a specific portion of template. In this example we
    are defining what will be inserted on <title/> tag.
     -->  
    <lift:with-param name="pageTitle">Lista of Suppliers</lift:with-param>
   
    <lift:with-param name="listTitle">List of Suppliers</lift:with-param>

    <lift:with-param name="listing">
        <!--
        The tag below will call the list method on Supplier
        class that is a snippet of this view.
        -->
        <lift:suppliers.list form="POST">
            <table>
                <tr>
                    <td></td>
                    <td></td>
                    <td width="200px" style="text-align: left;">Razao Social</td>
                    <td width="80px" style="text-align: left;">CNPJ</td>
                </tr>
                <suppliers:items/>
            </table>         
        </lift:suppliers.list>
        <br />
        <br />
        <center>
            <!--
            We are calling another snipper here where          
            we will handle form submission that will
            navigate to supplier registration page.
            -->
            <lift:suppliers.options form="POST">
                <new:submit/>
            </lift:suppliers.options>
        </center>
    </lift:with-param>
</lift:surround>

The code above give to us an idea about how we can create a view that consumes a lift template with the help of <lift:surround/> and <lift:with-param/> tags, we also know how to insert the snippet tag on the view. Now we are ready to take a closer look on snippet code to see how it works.

All Lift snippets are written in Scala language, the entire framework is written in Scala and application snippets aren’t a exception, in this snippet we will define a method called “list”, this method will execute a JPA query and will return a list of suppliers back, we will use list list to generate table rows, if there’s no suppliers on database a message will be rendered to the user instead of an html table.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package br.eti.faces.registration.snippet

import br.eti.faces.registration.model._
import Model._

import scala.xml.{NodeSeq, Text}
import net.liftweb._
import http._
import util._
import mapper._
import Helpers._
import S._

import javax.persistence.{EntityExistsException,PersistenceException}

class Suppliers {
 
  object _supplier extends SessionVar(new Supplier())  
  def supplier = _supplier.is
 
  def list(xhtml : NodeSeq): NodeSeq = {
   
    val suppliers = Model.createNamedQuery[Supplier]("findSuppliersByName")
      .setParameter("companyName", "%").getResultList()
 
    /*
    If the list of suppliers isn't empty then
    we can render this list on view, otherwise
    replace all snippet body with a message
    (see below).
    */

    if(suppliers.size > 0) {
        Helpers.bind("supplier", xhtml,
          "items"->
            suppliers.flatMap(it =>
              <tr>
                <td>{SHtml.submit("Edit", () => edit(it), ("id", "btnEdit"))}</td>
                <td>{SHtml.submit("Delete", () => delete(it), ("id", "btnDelete"))}</td>
                <td>{Text(it.companyName}</td>
                <td>{Text(it.id)}</td>
              </tr>      
        ))
    }
    /*
    There's no data to list to the user,
    replace the <lift:suppliers.list />
    body with the markup below.
    */

    else {
      <big>
        <span id="message"><b>No suppliers found!</b></span>
      </big>
    }
  }
}

You could see how easy is control the rendering of snippet body, you only need do simple checks on the data returned from database before render any markup.

Share

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>