Lift Application Development Cookbook

By Gilberto T. Garcia Jr.
  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Getting Started with Lift Basics

About this book

Developing secure web applications is one of the most important tasks developers have to deal with. With Lift, it is easy to create solid and formidable web applications as it is the most secure web framework available today. The View-First approach and being able to handle things as purely data transformation, makes working with Lift an exciting task.

"Lift Application Development Cookbook" teaches you how to build web applications using this amazing framework. The book moves gradually, starting with the basics (starting a new project, submitting a form, and so on) before covering more advanced topics such as building a REST API and integrating your application with other technologies and applications.

"Lift Application Development Cookbook" takes you on a journey of creating secure web applications. Step-by-step instructions help you understand how things work and how various elements relate to each other.

You'll learn different ways to process a form, build dynamic HTML pages, and create an API using REST. You'll also learn how to work with relational and NoSQL databases and how to integrate your application with other technologies as well as with third-part applications such as Gmail and Facebook.

By the end of the book, you will be able to understand how Lift works and be able to build web applications using this amazing and exciting framework.

Publication date:
September 2013
Publisher
Packt
Pages
254
ISBN
9781849515887

 

Chapter 1. Getting Started with Lift Basics

In this chapter, we will learn about:

  • Creating a Lift application using SBT

  • Creating a Lift application using Maven

  • Defining a SiteMap

  • Logging using logback

  • Sending e-mails using Gmail's SMTP server

 

Introduction


In this chapter, we will learn how to install Lift, which is a very secure web framework written in Scala; how to configure the basics of a Lift application such as how to define the SiteMap which is a comprehensive representation of the pages of a Lift application; and how to configure a log engine. We will also learn how to create an application using Simple Build Tool (SBT) or Maven.

 

Creating a Lift application using SBT


SBT is a build tool for Scala and Java projects. The idea of using a build tool such as SBT is to make it easier to manage all of the project dependencies. Also, it helps to ensure that the application generated by the build process is always the same. This means that it doesn't matter whether the application is built on my computer or yours, the end result will be the same.

The easiest way to start with Lift and SBT is by downloading them from the official website. There, you can find a list of tar.gz and .zip files containing everything you need to start using Lift.

Getting ready

Scala, and in turn, the Lift development requires a JVM and because of this, you'll need to install Java 7 on your computer. However, you can skip this step if you already have it installed. If not then go to http://java.com and click on the Free Java Download button. Then, download and install the JDK appropriate for your OS.

How to do it...

Carry out the following steps:

  1. First of all, to install and run Lift on Windows, you will need to download the Lift 2.5 ZIP file, which is the latest stable release, from http://liftweb.net/download.

  2. After the download is complete, open Windows Explorer and extract the contents from the file.

  3. Then, go to scala_210/ift_basic, double click on the sbt.bat file to run SBT, and wait until SBT finishes downloading the required libraries. This process can take a while depending on the speed of your internet connection.

    When the download part is completed, you will get the SBT prompt that can be recognized by the > character.

  4. After getting into the SBT prompt, type the following command to start the basic Lift application:

    > container:start
    
  5. At this point, we have a running Lift application. So, open up your favorite browser and go to http://localhost:8080. Then you should see a welcome window similar to the following screenshot:

  6. To exit SBT, you just need to type the following command in the SBT prompt:

    > exit
    

How it works...

The ZIP file contains some examples of Lift applications such as a blank application that you can use to start your application from scratch. It also contains a basic Lift application that contains Blueprint CSS and ready-to-use Mapper models, which you can use as the start point when building your own application.

The lift_basic folder contains a working Lift application. This means that you have SBT and a configured, ready-to-use project in it.

When we ran SBT, it started to download all the required libraries that the application needs (these dependencies are defined in the build.sbt file). Once this step is done, we can start the application.

After downloading the required libraries, we ran the container:start command provided by the sbt-web-plugin that deploys the Lift application into an embedded Jetty server.

You can see that inside the lift_basic application, there is a folder called project which contains a file called project.sbt. In that file, you will see that it defines three plugins for SBT. The first defined plugin is the XSBT plugin. After the XSBT plugin, there is the sbt-idea plugin and the sbteclipse plugin. The former is to enable SBT to be integrated with IntelliJ IDEA, and the latter enables SBT to be integrated with Scala IDE. Another thing to notice in the plugins.sbt file is that it matches the version of SBT to select the correct version of the sbt-web-plugin.

There's more...

To install and run Lift on Linux or Mac, perform the following steps:

  1. Download the Lift 2.5 ZIP or the tar.gz file from http://liftweb.net/download.

  2. Once you've got the file, open a shell tool and expand it.

  3. Then, go to scala_210/lift_basic, and start SBT by running the following command:

    ./sbt
    
  4. You can then continue from step 4 of the How to do it… section.

See also

 

Creating a Lift application using Maven


In the previous recipe, we learned how to use SBT to create and run a Lift application. Now I will show you how to set up and run a Lift application using Maven, which is another build tool.

Getting ready

If you don't have Maven installed and configured on your computer, go to http://maven.apache.org/download.cgi, download Maven 3.1.0, and follow the installation instructions.

How to do it...

We will use a Maven archetype that will create a ready-to-use Lift application for us.

  1. Open a cmd window and run the following command:

    mvn archetype:generate ^
      -DarchetypeGroupId=net.liftweb ^
      -DarchetypeArtifactId=lift-archetype-basic_2.9.1 ^
      -DarchetypeVersion=2.5 ^
      -DarchetypeRepository=https://oss.sonatype.org/content/repositories/releases
    ^
      -DgroupId=lift.cookbook ^
      -DartifactId=chap01-mvn ^
      -Dversion=1.0
    

    After running the previous command, Maven will start to download all the required libraries to create the project.

  2. Once the download is complete, Maven will ask you to confirm some information about the project. Confirm them by typing Y and pressing return.

  3. Change the following tags in the pom.xml file:

    From:

    <scala.version>2.9.1</scala.version>

    To:

    <scala.version>2.10</scala.version>

    From:

    <artifactId>lift-mapper_2.9.1</artifactId>

    To:

    <artifactId>lift-mapper_2.10</artifactId>

    From:

    <artifactId>lift-jquery-module_2.9.1</artifactId>
    <version>2.5-2.0</version>

    To:

    <artifactId>lift-jquery-module_2.5_2.10</artifactId>
    <version>2.4</version>

    From:

    <groupId>org.scala-tools</groupId>
    <artifactId>maven-scala-plugin</artifactId>
    <version>2.15.2</version>

    To:

    <groupId>net.alchim31.maven</groupId>
    <artifactId>scala-maven-plugin</artifactId>
    <version>3.1.5</version>

    From:

    <groupId>org.mortbay.jetty</groupId>
    <artifactId>maven-jetty-plugin</artifactId>
    <version>6.1.26</version>

    To:

    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
  4. When you have finished editing the pom.xml file, open a cmd window, go to the folder containing the pom.xml file, and run the following command to update and compile the project:

    mvn compile
    
  5. Once Maven finishes the compilation, you will be able to start the application by running the following command:

    mvn jetty:run
    
  6. Now that you have the application up and running, you can access http://localhost:8080 in your favorite browser, and you should see a welcome page similar to the following:

How it works...

When you create a project using the Lift archetype, you get a fully working application containing everything you need to build your own application. This means that Maven will create an application with its default directory structure, a pom.xml file, with everything needed by the sample application. It will also include the jetty plugin that will allow us to run the application by running the jetty:run command.

The application created by Maven is a sample application that contains Blueprint CSS and a Mapper model. One more thing to notice is that this archetype also includes plugins for IntelliJ IDEA and Scala IDE.

See also

To learn more about Maven, please go to http://maven.apache.org/.

 

Defining a SiteMap


Lift offers several ways for programmers to define which pages their applications will have. SiteMap is one of these ways. Besides defining the pages of your application, you can also control the access of each URL. This means that you can, for example, control whether a URL will have access restrictions or not and even control the restriction level of any given URL.

What does this mean? This means that you can think of SiteMap as the defined structure of your application containing every URL that will be accessible and the policies that are applied for each one of them.

Another thing that SiteMap does is automatic mapping between URLs and XHTML templates.

In this recipe, we will see how to configure SiteMap for a simple application. For this, let's suppose we want to create an application to store and manage contacts.

We will need one URL for each of the following actions:

  • List contacts

  • Create contacts

  • Edit contacts

  • Delete contacts

  • View contacts' details

Getting ready

Copy the contents of the lift_blank folder from the scala_29 folder to a new directory called contacts-app.

How to do it...

Carry out the following steps:

  1. Edit the Boot.scala file by adding a function, LocParam, just before the declaration of the entries value:

    val canManage_? = If(() => {
      true
    }, () => RedirectResponse("/"))

    This is to verify whether the user accessing the URL has management permission and is allowed to access it.

  2. Then, add another LocParam to check whether the user has administrative privileges:

    val isAdmin_? = If(() => {
      false
    }, () => RedirectWithState("/contacts/list",MessageState("Authorized personnel only" -> NoticeType.Warning)))
  3. After creating the functions, we'll define SiteMap by adding new menu items between the Menu.i("Home") / "index" and the Menu(Loc("Static", … entries.

    Menu items that need to be added are as follows:

    Menu.i("List Contacts") / "contacts" / "list",
    Menu.i("Create") / "contacts" / "create" >> canManage_?,
    Menu.i("Edit") / "contacts" / "edit" >> canManage_?,
    Menu.i("Delete") / "contacts" / "delete" >> isAdmin_?,
    Menu.i("View") / "contacts" / "view" >> canManage_?,
  4. Create a folder called contacts inside the webapp folder.

  5. Create five HTML files, one for each menu item defined in SiteMap:

    • list.html

    • create.html

    • edit.html

    • delete.html

    • view.html

  6. Then run the application and go to the URL http://localhost:8080 in your browser. The following screen will be displayed:

How it works...

Lift will build the SiteMap object during the application boot process as a result of the invocation of the method, LiftRules.setSiteMap.

When a user tries to access, for example /contacts/list, Lift will use SiteMap to decide whether the resource is defined or not by matching the URL against the link list defined by the menu entries in SiteMap. Since we've defined it, Lift will serve the page to the user. However, if the user tries to access /contacts/lists, the match will fail and Lift will return a 404 error.

We still need to understand what the LocParam functions are that were mentioned in steps 1 and 2. LocParam is something that modifies how Lift handles the given entry of SiteMap. In our case, it is a function that redirects the user to a different URL if the condition being tested fails. So, if someone tries to access /contacts/create, Lift will execute the canManage_? function after matching the URL. If the function returns true, Lift will serve the page to the user; otherwise, it will redirect the user to /. The same logic applies to the view and edit URLs.

The same logic applies to the delete link; the only difference being the fact that the isAdmin_? function not only redirects the user to /, but also passes a message that will be displayed in the page. This happens because we've used If LocParam that takes two arguments. The first is a test function. If it returns true, the page can be accessed; and if the return value is false, the result of evaluating the second parameter, FailMsg, will be sent to the browser.

There's more...

The entries variable is a list of menu items that will be processed when the application is started by Jetty.

Each menu item has a structure as shown in the following image.

  • Unique identifier

  • Link object

  • Text

  • Parameters

The unique identifier is used by Lift to keep a track of all the menu entries in SiteMap.

The Link contains the list that will be used to match the requested URL to check if it is defined or not.

The match head parameter, which is a Boolean value, defines whether Lift will match the exact URL or everything beginning with the given path. Notice that if you pass true, Lift will serve URLs containing /contacts/create or /contacts/create/*, where * is any HTML file existing inside webapps/contacts/create. If no such folder exists, Lift will return a 404 error. If you pass false, Lift will only serve /contacts/create and will return the 404 error for any other URL containing /contacts/create.

The URL that will be used to create the link on the page will be the value rendered in the href attribute of the anchor tag, <a href={url}>...</a>.

text is the text that will be shown when the link is displayed.

The parameters are functions, LocParam, that you want to execute when rendering the link or accessing the page.

Lift comes with several types of the LocParam functions, such as MenuCssClass to add a CSS class to the Menu and Title to define the title of the page.

See also

To learn more about SiteMap, Menu, and the LocParam functions, please go to https://www.assembla.com/wiki/show/liftweb/SiteMap.

 

Logging using logback


Logback is a log engine that is intended to be a better version of the popular log4j. You might want to check the project website to understand the reasons you should consider Logback over log4j. But, you might ask why we need a log engine at all?

Logging is a useful tool that allows us to track what happens with the applications we build that are running on environments which we, as developers, cannot easily debug. That's why it is important that the tools we use to build applications support logging in an easy way. Lift does support logging in an easy and flexible manner. So, let us see how to log and what happens with our application.

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

Getting ready

We will use the code from the last section to re-use the SiteMap we have defined.

How to do it...

Don't worry if you don't fully understand the following code. We will get back to it later in the book.

  1. Create a new Scala class called ListUser inside the snippet package with the following code:

    class ListUser extends Logger {
      def log(text: String) {
        text match {
          case str if str.length == 0 =>
            error("user with no name")
          case str if str == "Forbidden" =>
            warn("this user shouldn't have access")
          case str =>
            debug("User name: " + str)
        }
      }
      def list = {
        val users = List("John", "Sarah", "Peter", "Sam", "","Forbidden")
        info("listing users")
        "li .name *" #> users.map {
          user => {
            log(user)
            Text(user)
          }
        }
      }
    }
  2. Add the following HTML snippet in /webapp/contacts/list.html:

    <ul data-lift="ListUser.list">
      <li class="name"><!-- user names will be in here --></li>
    </ul>
  3. Change the code.snippet logger in src/main/resources/logback.xml to debug the level as follows:

    <logger name="code.snippet" level="debug" />
  4. Start the application and go to http://localhost:8080/contacts/list in your browser.

    In your browser, you will see, a page similar to the one shown in the following screenshot:

    In the SBT console, you will see a log similar to the following screenshot:

How it works...

We configured the log in the logback.xml file. You might notice that there was an appender already configured. Appenders are the components that actually do the task of writing log events. There are several types of appenders and one of them is the ConsoleAppender that just prints the log entries in the standard output—the console in this case.

The class ListUser is a Lift snippet that traverses the list of strings defined by variable users. For each string, it does two things:

  • Invokes the log method

  • Adds the string inside the li tag

Then it returns the modified HTML to be rendered in the browser.

The log method will create a log entry with different log levels depending on the string's content, by invoking the method from the Logger trait which includes info, debug, error, warning, and so on.

The Logger trait's methods are accessible from the snippet because we mixed them in our snippet by extending them using extends Logger. Then the snippet is invoked by the instruction ListUser.list that we added in the data-lift attribute in the HTML file.

There's more...

When you use the Logger trait, Lift will create one logger per class or object. That is why we can see the object or class where the log entry was created. You can see in our example that the log was created by the ListUser snippet by extending the trait.

This is a nice feature since we can have more control of how our application creates the log entries. We can, for example, set packages with different log levels. As you can see in the logback.xml file, the code.snippet has the debug level while net.liftweb has the warn level and bootstrap.liftweb has the info level.

Logback is not the only log engine available. If you want to use log4j, you will need to change the dependency in the build.sbt file from:

"ch.qos.logback"    % "logback-classic"     % "1.0.6",

To:

"org.slf4j" % "slf4j-log4j12" % "1.6.1",

Also, you will need to create src/main/resources/log4j.xml, which is log4j's configuration file.

See also

 

Sending e-mails using Gmail's SMTP server


It does not matter if you are building your company website, an application that will be used only inside the company you work at, or an e-commerce solution. Eventually, you will need to send e-mails. It is fair to say that every web application has the need, at some point, to send e-mails.

In this recipe, we will learn how to send plain text e-mails using Gmail's SMTP server.

Getting ready

You can use the code of the examples we have used in the previous recipe, or you can start a new project.

How to do it...

Carry out the following steps:

  1. You will need to add the following properties into src/main/resources/default.props:

    [email protected]
    mail.password=your_password
  2. Change the mail.user and mail.password properties to match your Gmail account.

  3. Then create a method in the Boot class to configure the Mailer object as follows:

    def configureMailer() {
      import javax.mail{PasswordAuthentication, Authenticator}
      
      System.setProperty("mail.smtp.starttls.enable", "true")
      System.setProperty("mail.smtp.ssl.enable", "true")
      System.setProperty("mail.smtp.host", "smtp.gmail.com")
      System.setProperty("mail.smtp.auth", "true")
      
      Mailer.authenticator = for {
        user <- Props.get("mail.user")
        pass <- Props.get("mail.password")
      } yield new Authenticator {
        override def getPasswordAuthentication =
        new PasswordAuthentication(user, pass)
      }
    }
  4. Then, you need to call the configureMailer method from within the boot method:

    def boot {
      // where to search snippet
      LiftRules.addToPackages("code")
      
      configureMailer()
      ….
    }

    Now, we have the Mailer object configured, and we are ready to send e-mails.

  5. Inside the lib package src/main/scala/code/, create an object called SendEmail that will be responsible for sending e-mails:

    import net.liftweb.util.Mailer
    import net.liftweb.util.Mailer._
    
    object SendEmail {
      def send_!(from: String,
        recipient: String,
        subject: String,
      body: String) {
        val mailTypes = List(PlainMailBodyType(body), To(recipient))
        
        Mailer.msgSendImpl (
          From(from),
          Subject(subject),
        mailTypes)
      }
    }
  6. At last, we will create a snippet to render a link to send e-mails when clicked. For this, you will need to create a class called EmailSnippet inside the snippet package, src/main/scala/code/:

    import net.liftweb.http.SHtml
    import net.liftweb.util. Helpers._
    import code.lib.SendEmail
    import xml.Text
    import net.liftweb.util.Props
    
    class SEmail {
      def sendNow() = {
        SendEmail.send_!(
          Props.get("mail.user").get,
          "[email protected]",
          "Sending e-mail using GMail",
          "Here is the body content."
        )
      }
      
      def sendEmail = {
        "*" #> SHtml.link("#", () => sendNow(), Text("Send e-mail"))
      }
    }
  7. Change [email protected] to match your Gmail account.

  8. You will also need to create the following menu item in the entries list, just after the index entry:

    Menu.i("Send Email") / "send"
  9. Create a file called send.html inside src/main/webapp as follows:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <meta content="text/html; charset=UTF-8" http-equiv="content-type"/>
        <title>Home</title>
      </head>
      <body class="lift:content_id=main">
        <div id="main" class="lift:surround?with=default;at=content">
        <h2>Sending e-mail using GMail's SMTP server.</h2>
        
        <p>
          <span data-lift="EmailSnippet.sendEmail"><!-- there will be a button here --></span>
        </p>
        </div>
      </body>
    </html>
  10. Start the application and go to http://localhost:8080/send.

    You should see a page containing a link called Send e-mail, similar to the following screenshot:

  11. Click on the link to send the email, and you will receive an email in your Gmail inbox.

How it works...

First of all, we have set a few mail properties that will be used by the Java Mail API, such as mail.smtp.ssl.enable and mail.smtp.starttls.enable. These properties will enable SSL and TLS, meaning that we will use a secure channel to send the e-mail, and mail.smtp.host to set the SMTP server address. Then, we set mail.smtp.auth to true to use the SMTP authentication.

The next thing we did was to create an authenticator to use the Mailer object.

Note

Mailer is a built-in Lift object that contains utilities to send e-mails.

When creating the authenticator, we used the Props object to get the user and password values from the default.props file.

Note

Props is a Lift helper object that can be used to get values from properties files.

Then, we created the EmailSnippet class that creates a link which when clicked, invokes the sendNow() method. This method has no parameters and calls the SendEmail's send_! method, passing information such as from, to, subject, and body that will be used to send the e-mail. We had to wrap the call to send_! to keep the code easy to read. Then SendEmail's send_! invokes Mailer object's sendMail method, which is the method that will send the e-mail.

There's more...

Why did we do all of this in the Boot class? Well, we just needed to configure the Mailer object once. This is because it's a singleton, which means that only one instance of the object will be created, and we can use it throughout the application once it is configured. So, Boot is the perfect place to do this, since it is called only once when the server, in our case Jetty, is starting the application.

Note that we configured the Mailer object in a programmatic way. However, if you want to use The Java Naming and Directory Interface (JNDI) to configure the Mailer object, you will need to do two things.

Note

By using JNDI to configure the Mailer object, you can rely on the fact that the configurations will be set on the server; your application only needs to know the JNDI name to be able to use a given resource. This means that if you need to change the application server where your application will run, you won't have problems with different settings causing your application to break.

  1. First you need to call the following code instead of using the configureMailer() method:

    Mailer.jndiName = Full("mail/Session")
  2. Second, you need to configure the server to provide a mail session via JNDI. You do this by creating a file called jetty-env.xml inside the WEB-INF folder:

    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
    <Configure class="org.eclipse.jetty.webapp.WebAppContext">
      <New id="mail" class="org.eclipse.jetty.plus.jndi.Resource">
        <Arg>mail/Session</Arg>
        <Arg>
          <New class="org.eclipse.jetty.jndi.factories.MailSessionReference">
            <Set name="user">[email protected]</Set>
            <Set name="password">your_password</Set>
            <Set name="properties">
              <New class="java.util.Properties">
                <Put name="mail.transport.protocol">smtp</Put>
                <Put name="mail.smtp.host">smtp.gmail.com</Put>
                <Put name="mail.smtp.auth">true</Put>
                <Put name="mail.smtp.starttls.enable">true</Put>
                <Put name="mail.smtp.ssl.enable">true</Put>
                <Put name="mail.debug">true</Put>
              </New>
            </Set>
          </New>
        </Arg>
      </New>
    </Configure>

See also

You can get more information about the Mailer objects at the following addresses:

About the Author

  • Gilberto T. Garcia Jr.

    Gilberto T. Garcia Jr. has a Bachelor's degree in Philosophy from USP, and has been working with Internet-related technologies since 1999. He had worked with different programming languages in several projects with different sizes and complexities. As a person who enjoys learning new things, he started to study and work with Scala and Lift in 2010.

    Browse publications by this author
Book Title
Access this book, plus 7,500 other titles for FREE
Access now