Up: Part I

1 Welcome to Lift!

Welcome to Exploring Lift. We’ve created this book to educate you about Lift, which we think is a great framework for building compelling web applications. Lift is designed to make powerful techniques easily accessible while keeping the overall framework simple and flexible. It may sound like a cliché, but in our experience Lift makes it fun to develop because it lets you focus on the interesting parts of coding. Our goal for this book is that by the end, you’ll be able to create and extend any web application you can think of.

1.1 Why Lift?

For those of you have experience with other web frameworks such as Struts, Tapestry, Rails, et cetera, you must be asking yourself, "Why another framework? Does Lift really solve problems any differently or more effectively than the ones I’ve used before?" Based on our experience (and that of others in the growing Lift community), the answer is an emphatic, "Yes!" Lift has cherry-picked the best ideas from a number of other frameworks, while creating some novel ideas of its own. It’s this combination of a solid foundation and new techniques that makes Lift so powerful. At the same time, Lift has been able to avoid the mistakes made in the past by other frameworks. In the spirit of “convention over configuration,” Lift has sensible defaults for everything while making it easy to customize precisely what you need to: no more and no less. Gone are the days of XML file after XML file providing basic configuration for your application. Instead, a simple Lift app requires only that you add the LiftFilter to your web.xml and add one or more lines telling Lift what package your classes sit in (Section 3.2↓). The methods you code aren’t required to implement a specific interface (called a trait), although there are support traits that make things that much simpler. In short, you don’t need to write anything that isn’t explicitly necessary for the task at hand. Lift is intended to work out of the box, and to make you as efficient and productive as possible.
One of the key strengths of Lift is the clean separation of presentation content and logic, based on the bedrock concept of the Model-View-Controller pattern [A]  [A] http://java.sun.com/blueprints/patterns/MVC.html. One of the original Java web application technologies that’s still in use today is JSP, or Java Server Pages [B]  [B] http://java.sun.com/products/jsp/. JSP allows you to mix HTML and Java code directly within the page. While this may have seemed like a good idea at the start, it has proven to be painful in practice. Putting code in your presentation layer makes it more difficult to debug and understand what is going on within a page, and makes it more difficult for the people writing the HTML portion because the contents aren’t valid HTML. While many modern programming and HTML editors have been modified to accomodate this mess, proper syntax highlighting and validation don’t make up for having to switch back and forth between one or more files to follow the page flow. Lift takes the approach that there should be no code in the presentation layer, but that the presentation layer has to be flexible enough to accomodate any conceivable use. To that end, Lift uses a powerful templating system, à la Wicket [C]  [C] http://wicket.apache.org/, to bind user-generated data into the presentation layer. Lift’s templating is built on the XML processing capabilities of the Scala language [D]  [D] Not only does Scala have extensive library support for XML, but XML syntax is actually part of the language. We’ll cover this in more detail as we go through the book., and allows such things as nested templates, simple injection of user-generated content, and advanced data binding capabilities. For those coming from JSP, Lift’s advanced template and XML processing allows you essentially to write custom tag libraries at a fraction of the cost in time and effort.
Lift has another advantage over many other web frameworks: it’s designed specifically to leverage the Scala programming language. Scala is a relatively new language developed by Martin Odersky [E]  [E] Martin created the Pizza programming language, which led to the Generic Java (GJ) project that was eventually incorporated into Java 1.5. His home page is at http://lamp.epfl.ch/~odersky/ and his programming language research group at EPFL Switzerland. It compiles to Java bytecode and runs on the JVM, which means that you can leverage the vast ecosystem of Java libraries just as you would with any other Java web framework. At the same time, Scala introduces some very powerful features designed to make you, the developer, more productive. Among these features are an extremely rich type system along with powerful type inference, native XML processing, full support for closures and functions as objects, and an extensive high-level library. The power of the type system together with type inference has led people to call it “the statically-typed dynamic language” [F]  [F] http://scala-blogs.org/2007/12/scala-statically-typed-dynamic-language.html. That means you can write code as quickly as you can with dynamically-typed languages (e.g. Python, Ruby, etc.), but you have the compile-time type safety of a statically-typed language such as Java. Scala is also a hybrid functional (FP) and object-oriented (OO) language, which means that you can get the power of higher-level functional languages such as Haskell or Scheme while retaining the modularity and reusability of OO components. In particular, the FP concept of immutability is encouraged by Scala, making it well-suited for writing highly-concurrent programs that achieve high throughput scalability. The hybrid model also means that if you haven’t touched FP before, you can gradually ease into it. In our experience, Scala allows you to do more in Lift with fewer lines of code. Remember, Lift is all about making you more productive!
Lift strives to encompass advanced features in a very concise and straightforward manner. Lift’s powerful support for AJAX and Comet allows you to use Web 2.0 features with very little effort. Lift leverages Scala’s Actor library to provide a message-driven framework for Comet updates. In most cases, adding Comet support to a page involves nothing more than extending a trait [G]  [G] A trait is a Scala construct that’s almost like a Java interface. The main difference is that traits may implement methods and have fields. to define the rendering method of your page and adding an extra function call to your links to dispatch the update message. Lift handles all of the back-end and page-side coding to provide the Comet polling. AJAX support includes special handlers for doing AJAX form submission via JSON, and almost any link function can easily be turned into an AJAX version with a few keystrokes. In order to perform all of this client-side goodness, Lift has a class hierarchy for encapsulating JavaScript calls via direct JavaScript, jQuery, and YUI. The nice part is that you, too, can utilize these support classes so that code can be generated for you and you don’t have to put JavaScript logic into your templates.

1.2 What You Should Know before Starting

First and foremost, this is a book on the Lift framework. There are several things we expect you to be familiar with before continuing:

1.3 Typographical Conventions

In order to better communicate concepts and techniques in this book, we have adopted the following typographical conventions:
ClassNameMonospaced typewriter text is used to indicate types, class names, and other code-related information.
...Ellipses within code listings are used to indicate omission of code to condense listings. Unless otherwise noted, the example code in this book comes from the PocketChange app (Chapter 2 on page 1↓), which has full source code available on GitHub.

1.4 For More Information about Lift

Lift has a very active community of users and developers. Since its inception in early 2007 the community has grown to hundreds of members from all over the world. The project’s leader, David Pollak [H]  [H] http://blog.lostlake.org/, is constantly attending to the mailing list, answering questions, and taking feature requests. There is a core group of developers who work on the project, but submissions are taken from anyone who makes a good case and can turn in good code. While we strive to cover everything you’ll need to know in this book, there are several additional resources available for information on Lift:
  1. The first place to look is the Lift website at http://liftweb.net/. There are links to lots of information on the site. In particular:
    1. The Lift Wiki is hosted at http://www.assembla.com/wiki/show/liftweb. The Wiki is maintained not only by David, but also by many active members of the Lift community, including the authors. Portions of this book are inspired by and borrow from content on the Wiki. In particular, it has links to all of the generated documentation not only for the stable branch, but also for the unstable head, if you’re feeling adventurous. There’s also an extensive section of HowTos and articles on advanced topics that cover a wealth of information.
    2. The mailing list at http://groups.google.com/group/liftweb is very active, and if there are things that this book doesn’t cover, you should feel free to ask questions there. There are plenty of very knowledgeable people on the list that should be able to answer your questions. Please post specific questions about the book to the Lift Book Google Group at http://groups.google.com/group/the-lift-book. Anything else that is Lift-specific is fair game for the mailing list.
  2. Tim Perrett, another Lift committer, is writing a book on Lift for Manning called Lift in Action. More details can be found at the book’s site at http://www.manning.com/perrett/.
  3. Lift has an IRC channel at irc://irc.freenode.net/lift that usually has several people on it at any given time. It’s a great place to chat about issues and ideas concerning Lift.

1.5 Your First Lift Application

We’ve talked a lot about Lift and its capabilities, so now let’s get hands-on and try out an application. Before we start, though, we need to take care of some prerequisites:
Java 1.5 JDK Lift runs on Scala, which runs on top of the JVM. The first thing you’ll need to install is a modern version of the Java SE JVM, available at http://java.sun.com/. Recently Scala’s compiler was changed to target Java version 1.5. Version 1.4 is still available as a target, but we’re going to assume you’re using 1.5. Examples in this book have only been tested with Sun’s version of the JDK, although most likely other versions (e.g. Blackdown or OpenJDK) should work with little or no modification.
Maven 2 Maven is a project management tool that has extensive capabilities for building, dependency management, testing, and reporting. We assume that you are familiar with basic Maven usage for compilation, packaging, and testing. If you haven’t used Maven before, you can get a brief overview in appendix A↓. You can download the latest version of Maven from http://maven.apache.org/. Brief installation instructions (enough to get us started) are on the download page, at http://maven.apache.org/download.html.
A programming editor This isn’t a strict requirement for this example, but when we start getting into coding, it’s very helpful to have something a little more capable than Notepad. If you’d like a full-blown IDE with support for such things as debugging, continuous compile checking, etc., then there are plugins available on the Scala website at http://www.scala-lang.org/node/91. The plugins support:
Now that we have the prerequisites out of the way, it’s time to get started. We’re going to leverage Maven’s archetypes [I]  [I] An archetype is essentially a project template for Maven that provides prompt-driven customization of basic attributes. to do 99% of the work for us in this example. First, change to whatever directory you’d like to work in:
cd work
Next, we use Maven’s archetype:generate command to create the skeleton of our project:
mvn archetype:generate -U \
  -DarchetypeGroupId=net.liftweb \
  -DarchetypeArtifactId=lift-archetype-blank \
  -DarchetypeVersion=2.0 \
  -DarchetypeRepository=http://scala-tools.org/repo-releases \
  -DgroupId=demo.helloworld \
  -DartifactId=helloworld \
  -Dversion=1.0-SNAPSHOT
Maven should output several pages of text. It may stop and ask you to confirm the properties configuration, in which case you can just hit <enter>. At the end you should get a message that says BUILD SUCCESSFUL. You’ve now successfully created your first project! Don’t believe us? Let’s run it to confirm:
cd helloworld
mvn jetty:run
Maven should produce more output, ending with
[INFO] Starting scanner at interval of 5 seconds.
This means that you now have a web server (Jetty [J]  [J] http://www.mortbay.org/jetty/) running on port 8080 of your machine. Just go to http://localhost:8080/ and you’ll see your first Lift page, the standard “Hello, world!” With just a few simple commands, we’ve built a functional (albeit limited) web app. Let’s go into a little more detail and see exactly how these pieces fit together. First, let’s examine the index page. Whenever Lift serves up a request in which the URL ends with a forward slash, Lift automatically looks for a file called index.html [K]  [K] Technically, it also searches for some variations on index.html, including any localized versions of the page, but we’ll cover that later in section in that directory. For instance, if you tried to go to http://localhost:8080/test/, Lift would look for index.html under the test/ directory in your project. The HTML sources will be located under src/main/webapp/ in your project directory. Here’s the index.html file from our Hello World project:
<lift:surround with="default" at="content">
  <h2>Welcome to your project!</h2>
  <p><lift:helloWorld.howdy /></p>
</lift:surround>
This may look a little strange at first. For those with some XML experience, you may recognize the use of prefixed elements here. For those who don’t know what a prefixed element is, it’s an XML element of the form
<prefix:element>
In our case we have two elements in use: <lift:surround> and
<lift:helloWorld.howdy />
. Lift assigns special meaning to elements that use the “lift” prefix: they form the basis of lift’s extensive templating support, which we will cover in more detail in section 4.1↓. When lift processes an XML template, it does so from the outermost element inward. In our case, the outermost element is <lift:surround with=”default” at=”content”>. The <lift:surround> element basically tells Lift to find the template named by the with attribute (default, in our case) and to put the contents of our element inside of that template. The at attribute tells Lift where in the template to place our content. In Lift, this “filling in the blanks” is called binding, and it’s a fundamental concept of Lift’s template system. Just about everything at the HTML/XML level can be thought of as a series of nested binds. Before we move on to the <lift:helloWorld.howdy/> element, let’s look at the default template. You can find it in the templates-hidden directory of the web app. Much like the WEB-INF and META-INF directories in a Java web application, the contents of templates-hidden cannot be accessed directly by clients; they can, however, be accessed when they’re referenced by a <lift:surround> element. Here is the default.html file:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:lift="http://liftweb.net/">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    <meta name="description" content="" />
    <meta name="keywords" content="" />
                
    <title>demo.helloworld:helloworld:1.0-SNAPSHOT</title>
    <script id="jquery" src="/classpath/jquery.js" type="text/javascript"></script>
  </head>
  <body>
    <lift:bind name="content" />
    <lift:Menu.builder />
    <lift:msgs/>
  </body>
</html>
As you can see in the listing, this is a proper XHTML file, with <html>, <head>, and <body> tags. This is required since Lift doesn’t add these itself. Lift simply processes the XML from each template it encounters. The <head> element and its contents are boilerplate; the interesting things happen inside the <body> element. There are three elements here:
  1. The <lift:bind name=”content” /> element determines where the contents of our index.html file are bound (inserted). The name attribute should match the corresponding at attribute from our <lift:surround> element.
  2. The <lift:Menu.builder /> element is a special element that builds a menu based on the SiteMap (to be covered in chapter 7↓). The SiteMap is a high-level site directory component that not only provides a centralized place to define a site menu, but allows you to control when certain links are displayed (based on, say, whether users are logged in or what roles they have) and provides a page-level access control mechanism.
  3. The <lift:msgs /> element allows Lift (or your code) to display messages on a page as it’s rendered. These could be status messages, error messages, etc. Lift has facilities to set one or more messages from inside your logic code.
Now let’s look back at the <lift:helloWorld.howdy /> element from the index.html file. This element (and the <lift:Menu.builder /> element, actually) is called a snippet, and it’s of the form
<lift:class.method>
Where class is the name of a Scala class defined in our project in the demo.helloworld.snippets package and method is a method defined on that class. Lift does a little translation on the class name to change camel-case back into title-case and then locates the class. In our demo the class is located under src/main/scala/demo/helloworld/snippet/HelloWorld.scala, and is shown here:
package demo.helloworld.snippet
​
class HelloWorld {
  def howdy = <span>Welcome to helloworld at 
    {new _root_.java.util.Date}</span>
}
As you can see, the howdy method is pretty straightforward. Lift binds the result of executing the method (in this case a span) into the location of the snippet element. It’s interesting to note that a method may itself return other <lift:...> elements in its content and they will be processed as well. This recursive nature of template composition is part of the fundamental power of Lift; it means that reusing snippets and template pieces across your application is essentially free. You should never have to write the same functionality more than once.
Now that we’ve covered all of the actual content elements, the final piece of the puzzle is the Boot class. The Boot class is responsible for the configuration and setup of the Lift framework. As we’ve stated earlier in the chapter, most of Lift has sensible defaults, so the Boot class generally contains only the extras that you need. The Boot class is always located in the bootstrap.liftweb package and is shown here (we’ve skipped imports, etc):
package bootstrap.liftweb
​
import net.liftweb.util._
import net.liftweb.http._
import net.liftweb.sitemap._
import net.liftweb.sitemap.Loc._
import Helpers._
 
/**
  * A class that’s instantiated early and run.  It allows the application
  * to modify Lift’s environment
  */
class Boot {
  def boot {
    // where to search snippet
    LiftRules.addToPackages("demo.helloworld")     
​
    // Build SiteMap
    val entries = 
      Menu(Loc("Home", List("index"), "Home")) :: 
      Nil 
    LiftRules.setSiteMap(SiteMap(entries:_*))
  }
}
There are two basic configuration elements, placed in the boot method. The first is the
LiftRules.addToPackages method. It tells lift to base its searches in the demo.helloworld package. That means that snippets would be located in the demo.helloworld.snippets package, views (section 4.4↓) would be located in the demo.helloworld.views package, etc. If you have more than one hierarchy (i.e. multiple packages), you can just call addToPackages multiple times. The second item in the Boot class is the SiteMenu setup. Obviously this is a pretty simple menu in this demo, but we’ll cover more interesting examples in the SiteMap chapter.
Now that we’ve covered a basic example we hope you’re beginning to see why Lift is so powerful and why it can make you more productive. We’ve barely scratched the surface of Lift’s templating and binding capabilities, but what we’ve shown here is already a big step. In roughly ten lines of Scala code and about thirty in XML, we have a functional site. If we wanted to add more pages, we’ve already got our default template set up so we don’t need to write the same boilerplate HTML multiple times. In our example we’re directly generating the content for our helloWorld.howdy snippet, but in later examples we’ll show just how easy it is to pull content from the template itself into the snippet and modify it as needed.
In the following chapters we’ll be covering
We hope you’re as excited about getting started with Lift as we are!
Up: Part I

(C) 2012 Lift 2.0 EditionWritten by Derek Chen-Becker, Marius Danciu and Tyler Weir