SlideShare a Scribd company logo
1 of 46
Download to read offline
Overview of Lift Web Framework




Vikas Hazrati
www.xebiaindia.com
Today There is a Wide Choice of
       Web Frameworks
As Developers It is Hard to Make a
            Choice
Every Framework Has its Own Set
           of Pitfalls
But Quick Development is Still an
            Option
Why is Lift Better?
      Convention over
       configuration                            Clean separation of presentation
                                                       content and logic




       Leverage the                                                 Responsive
Scala programming language                                          community




     Concise code increases                            Powerful AJAX & Comet
          productivity                                        Support


                              Highly Scalable
mvn archetype:generate -U 
 -DarchetypeGroupId=net.liftweb 
 -DarchetypeArtifactId=lift-archetype-blank 
 -DarchetypeVersion=1.0 
 -DremoteRepositories=http://scala-tools.org/repo-
releases 
 -DgroupId=demo.helloworld 
 -DartifactId=helloworld 
 -Dversion=1.0-SNAPSHOT




           cd helloworld
           mvn jetty:run
index.html

 <lift:surround with="default" at="content">
 <h2>Welcome to your project!</h2>
 <p><lift:helloWorld.howdy /></p>
 </lift:surround>




class HelloWorld {
  def howdy = <span>Welcome to helloworld at {new
_root_.java.util.Date}</span>
}
default.html
<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>
Boot Class
package bootstrap.liftweb

import    _root_.net.liftweb.util._
import    _root_.net.liftweb.http._
import    _root_.net.liftweb.sitemap._
import    _root_.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:_*))
    }
}
Lift Entry Point
<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<filter>
  <filter-name>LiftFilter</filter-name>
  <display-name>Lift Filter</display-name>
  <description>The Filter that intercepts lift
calls</description>
  <filter-class>net.liftweb.http.LiftFilter</filter-class>
</filter>


<filter-mapping>
  <filter-name>LiftFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

</web-app>
Lift’s Main Objects


  net.liftweb.http.S
                             net.liftweb.http.SHtml


net.liftweb.http.LiftRules
Template           Snippets




           Boot               Adding AJAX
           class                 Spice




           Model
Model
Maps to rdbms




class ToDo extends LongKeyedMapper[ToDo] with IdPK {
  def getSingleton = ToDo
  object done extends MappedBoolean(this)
  object owner extends MappedLongForeignKey(this, User)
  object priority extends MappedInt(this) {
    override def defaultValue = 5
  }
  object desc extends MappedPoliteString(this, 128)
}
object ToDo extends ToDo with LongKeyedMetaMapper[ToDo]

                                     Provides meta functionality
                                           Like finders etc
Persistence
Mapper and Record Frameworks
                            Per instance
     Mapper

                                 Global
   MetaMapper
                                                           Record
                                Per field
   MappedField


<project ...>
...
<dependencies>
  ...
  <dependency>
    <groupId>net.liftweb</groupId>
    <artifactId>lift-mapper</artifactId>
    <version>1.0</version> <!-- or 1.1-SNAPSHOT, etc -->
  </dependency>
</dependencies>
...
</project>
Database Connection
class Boot {
 def boot {
   ...
   DB.defineConnectionManager(DefaultConnectionIdentifier, DBVendor)
  Schemifier.schemify(true, Log.infoF _, User, ToDo)



           import _root_.net.liftweb.mapper._
           import _root_.java.sql._
           object DBVendor extends ConnectionManager {
            // Force load the driver
            Class.forName("org.postgresql.Driver")
            // define methods
            def newConnection(name : ConnectionIdentifier) = {
              try {
                Full(DriverManager.getConnection(
                   "jdbc:postgresql://localhost/mydatabase",
                   "root", "secret"))
              } catch {
                case e : Exception => e.printStackTrace; Empty
              }
            }
            def releaseConnection (conn : Connection) { conn.close }
import _root_.java.math.MathContext
class Expense extends LongKeyedMapper[Expense] with IdPK {
  def getSingleton = Expense
  object dateOf extends MappedDateTime(this)
  object description extends MappedString(this,100)
  object amount extends MappedDecimal(this, MathContext.DECIMAL64, 2)
  object account extends MappedLongForeignKey(this, Account)
}



create            save           delete       count     countByInsecureSQL


findAll         findAllByInsecureSQL      findAllByPreparedStatement


         findAllFields
Templates
Templates

                Lift tag


<lift:surround with="default" at="content">
<head><title>Hello!</title></head>
<lift:Hello.world />
</lift:surround>
                                  Snippet
Views
    class ExpenseView extends LiftView {
     override def dispatch = {
       case "enumerate" => doEnumerate _
     }
     def doEnumerate () : NodeSeq = {
       ...

        <lift:surround with="default" at="content">
        { expenseItems.toTable }
        </lift:surround>
    }
}
Tags
<lift:snippet type="MyClass:render" />        snippet
<lift:MyClass.render />
<lift:MyClass />
                                                            surround
<lift:surround with="template_name" at=”binding”>
        children
</lift:surround>

 <lift:bind name=”binding_name” />           bind


  <div class="accountUpdates">
  < lift : comet type="AccountMonitor">             comet
    <ul><account:entries>
      <li><entry:time/> : <entry:user /> :
 <entry:amount /></li>
    </account:entries></ul>
  </ lift : comet>
  </div>
Snippets




View              Logic
<lift:Util.out>                    Lift tags
         Please Log In <b>Dude</b>
         </lift:Util.out>


                                             Corresponding
                                                Snippet
package com.liftworkshop.snippet                 code
import scala.xml.{NodeSeq}
import com.liftworkshop._
import model._
class Util {
  def in(html: NodeSeq) =
   if (User.loggedIn_?) html else NodeSeq.Empty
  def out(html: NodeSeq) =
   if (!User.loggedIn_?) html else NodeSeq.Empty
}
Snippets
 class Ledger {
   def balance (content : NodeSeq) : NodeSeq =
 Text(currentLedger.formattedBalance)
 }
                              class Ledger {
                                def balance (content : NodeSeq) : NodeSeq =
                                 <p>{currentLedger.formattedBalance}
                                 as of <lift:Util.time /></p>
                              }


<lift:Ledger.balance>
<ledger:balance/> as of <ledger:time />
</lift:Ledger.balance>
                                      class Ledger {
                                        def balance (content : NodeSeq ) : NodeSeq =
                                         bind ("ledger", content,
                                            "balance" -> Text(currentLedger.formattedBalance),
                                            "time" -> Text((new java.util.Date).toString))
                                      }
Snippets are Stateless
               Cookies




             SessionVar




             RequestVar



            StatefulSnippet
               Subclass
Form Processing




Post/Get
                             JSON

                AJAX
Form Processing
<html>
...
<lift:Show.myForm form="POST">
 <tr>
  <td>Name</td>
  <td><f:name><input type="text"/></f:name></td>
 </tr>
 <tr>
  <td>Birthyear</td>
  <td><f:year>
       <select><option>2007</option></select>
  </f:year></td>
 </tr>
 <tr>
  <td>&nbsp;</td>
  <td><input type="submit" value="Add"/></td>
 </tr>
</lift:Show.myForm>
</html>
Form Processing

class Show {
  def myForm(xhtml: NodeSeq) = {
    var name = ""
    def handleYear(year: String) {
      ... the form’s been submitted... do something
    }
    bind("f", xhtml, "name" -> text(name, name = _),
               "year" -> select((1900 to 2007).
                    toList.map(_.toString).
                    reverse.map(v => (v, v)),
                    Empty, handleYear _))
  }
}
Goodies
ProtoUser and MegaProtoUser




                                  class User extends ProtoUser[User] {
                                  override def shortName = firstName.is
                                  override lastNameDisplayName = "surname"
                              }
AJAX and Comet
JavaScript
import JsCmds._
import JE._
var myName = ""
bind(...
  "name" -> text(myName, myName = _, "id" -> "myName"),
  "submit" -> submit("Save", ..., "onclick" ->
   JsIf(JsEq(ValById("myName"), ""),
     Alert("You must provide a name") & JsReturn(false))
   )
)


import net.liftweb.http.js.yui.YUIArtifacts
class Boot {
  def boot = {
   ...
   LiftRules.jsArtifacts = YUIArtifacts
   ...
}
AJAX and Comet
AJAX and Comet
Comet Based on Scala Actors
AJAX
 <lift:TD.list all_id="all_todos">
 <div id="all_todos">
   <div>Exclude done <todo:exclude/></div>
   <ul>
    <todo:list>
         <li>
        <todo:check><input type="checkbox"/></todo:check>
        <todo:priority>
          <select><option>1</option></select>
        </todo:priority>
        <todo:desc>To Do</todo:desc>
      </li>
    </todo:list>
   </ul>
 </div>
</lift:TD.list>
def list(html: NodeSeq) = {
  val id = S.attr("all_id").open_!
  def inner(): NodeSeq = {
    def reDraw() = SetHtml(id, inner())
    bind("todo", html,
        "exclude" ->
          ajaxCheckbox(QueryNotDone, v =>
{QueryNotDone(v); reDraw}),
        "list" -> doList(reDraw) _)
  }
  inner()              private def doList(reDraw: () => JsCmd)(html: NodeSeq):
}                      NodeSeq =
                        toShow.
                        flatMap(td =>
                         bind("todo", html,
                             "check" -> ajaxCheckbox(td.done,
                                      v => {td.done(v).save; reDraw()}),
                             "priority" ->
                             ajaxSelect(ToDo.priorityList,
                       Full(td.priority.toString),
                                      v => {td.priority(v.toInt).save;
                       reDraw()}),
                             "desc" -> desc(td, reDraw)
                         ))


  private def desc(td: ToDo, reDraw: () => JsCmd) =
 swappable(<span>{td.desc}</span>,
         <span>{ajaxText(td.desc,
                     v => {td.desc(v).save; reDraw()})}
         </span>)
Comet
<lift:surround with="default" at="content">
  <lift:comet type="Clock" name="Other">
          Current Time: <clk:time>Missing Clock</clk:time>
     </lift:comet>
</lift:surround>
                                    class Clock extends CometActor {
                                     override def defaultPrefix = Full("clk")
                                     def render = bind("time" -> timeSpan)
                                     def timeSpan = (<span id="time">{timeNow}</span>)
                                     // schedule a ping every 10 seconds so we redraw
                                     ActorPing.schedule(this, Tick, 10000L)
                                     override def lowPriority : PartialFunction[Any, Unit] = {
                                       case Tick => {
                                         println("Got tick " + new Date());
                                         partialUpdate(SetHtml("time", Text(timeNow.toString)))
                                         // schedule an update in 10 seconds
                                         ActorPing.schedule(this, Tick, 10000L)
                                       }
                                     }
                                   }
                                   case object Tick
Lift Architecture
Rails v/s Lift

For single request processing, the lift code, running inside Tomcat, ran 4
times faster than the Rails code running inside Mongrel. However, the CPU
utilization was less than 5% in the lift version, where it was 100% of 1 CPU
(on a dual core machine) for the Rails version. For multiple simultaneous
requests being made from multiple machines, we're seeing better than 20x
performance of the lift code versus the Rails code with 5 Mongrel instances.
Once again, the lift code is not using very much CPU and the Rails code is
pegging both CPUs.


                        http://lambda-the-ultimate.org/node/2147
Lots of Choices
Overview Of Lift Framework

More Related Content

What's hot

EWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode ObjectsEWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode ObjectsRob Tweed
 
td_mxc_rubyrails_shin
td_mxc_rubyrails_shintd_mxc_rubyrails_shin
td_mxc_rubyrails_shintutorialsruby
 
Brew up a Rich Web Application with Cappuccino
Brew up a Rich Web Application with CappuccinoBrew up a Rich Web Application with Cappuccino
Brew up a Rich Web Application with CappuccinoHoward Lewis Ship
 
From framework coupled code to #microservices through #DDD /by @codelytv
From framework coupled code to #microservices through #DDD /by @codelytvFrom framework coupled code to #microservices through #DDD /by @codelytv
From framework coupled code to #microservices through #DDD /by @codelytvCodelyTV
 
EWD 3 Training Course Part 9: Complex QEWD Messages and Responses
EWD 3 Training Course Part 9: Complex QEWD Messages and ResponsesEWD 3 Training Course Part 9: Complex QEWD Messages and Responses
EWD 3 Training Course Part 9: Complex QEWD Messages and ResponsesRob Tweed
 
High Performance XQuery Processing in PHP with Zorba by Vikram Vaswani
High Performance XQuery Processing in PHP with Zorba by Vikram VaswaniHigh Performance XQuery Processing in PHP with Zorba by Vikram Vaswani
High Performance XQuery Processing in PHP with Zorba by Vikram Vaswanivvaswani
 
Simplify AJAX using jQuery
Simplify AJAX using jQuerySimplify AJAX using jQuery
Simplify AJAX using jQuerySiva Arunachalam
 
Test-driven Development with AEM
Test-driven Development with AEMTest-driven Development with AEM
Test-driven Development with AEMJan Wloka
 
Node.js in action
Node.js in actionNode.js in action
Node.js in actionSimon Su
 
Unit Testing at Scale
Unit Testing at ScaleUnit Testing at Scale
Unit Testing at ScaleJan Wloka
 
Build Widgets
Build WidgetsBuild Widgets
Build Widgetsscottw
 
JavaFX and Scala in the Cloud
JavaFX and Scala in the CloudJavaFX and Scala in the Cloud
JavaFX and Scala in the CloudStephen Chin
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperJon Kruger
 
HTML5 JavaScript APIs
HTML5 JavaScript APIsHTML5 JavaScript APIs
HTML5 JavaScript APIsRemy Sharp
 

What's hot (19)

Alfredo-PUMEX
Alfredo-PUMEXAlfredo-PUMEX
Alfredo-PUMEX
 
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode ObjectsEWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
 
td_mxc_rubyrails_shin
td_mxc_rubyrails_shintd_mxc_rubyrails_shin
td_mxc_rubyrails_shin
 
Brew up a Rich Web Application with Cappuccino
Brew up a Rich Web Application with CappuccinoBrew up a Rich Web Application with Cappuccino
Brew up a Rich Web Application with Cappuccino
 
From framework coupled code to #microservices through #DDD /by @codelytv
From framework coupled code to #microservices through #DDD /by @codelytvFrom framework coupled code to #microservices through #DDD /by @codelytv
From framework coupled code to #microservices through #DDD /by @codelytv
 
EWD 3 Training Course Part 9: Complex QEWD Messages and Responses
EWD 3 Training Course Part 9: Complex QEWD Messages and ResponsesEWD 3 Training Course Part 9: Complex QEWD Messages and Responses
EWD 3 Training Course Part 9: Complex QEWD Messages and Responses
 
High Performance XQuery Processing in PHP with Zorba by Vikram Vaswani
High Performance XQuery Processing in PHP with Zorba by Vikram VaswaniHigh Performance XQuery Processing in PHP with Zorba by Vikram Vaswani
High Performance XQuery Processing in PHP with Zorba by Vikram Vaswani
 
Simplify AJAX using jQuery
Simplify AJAX using jQuerySimplify AJAX using jQuery
Simplify AJAX using jQuery
 
Test-driven Development with AEM
Test-driven Development with AEMTest-driven Development with AEM
Test-driven Development with AEM
 
Node.js in action
Node.js in actionNode.js in action
Node.js in action
 
Unit Testing at Scale
Unit Testing at ScaleUnit Testing at Scale
Unit Testing at Scale
 
Build Widgets
Build WidgetsBuild Widgets
Build Widgets
 
jQuery Objects
jQuery ObjectsjQuery Objects
jQuery Objects
 
JavaFX and Scala in the Cloud
JavaFX and Scala in the CloudJavaFX and Scala in the Cloud
JavaFX and Scala in the Cloud
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
 
YouDrup_in_Drupal
YouDrup_in_DrupalYouDrup_in_Drupal
YouDrup_in_Drupal
 
JavaScript JQUERY AJAX
JavaScript JQUERY AJAXJavaScript JQUERY AJAX
JavaScript JQUERY AJAX
 
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter PilgrimJavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
 
HTML5 JavaScript APIs
HTML5 JavaScript APIsHTML5 JavaScript APIs
HTML5 JavaScript APIs
 

Viewers also liked

Banking application & software solutions at competitive rate
Banking application & software solutions at competitive rateBanking application & software solutions at competitive rate
Banking application & software solutions at competitive rateAaron Jacobson
 
Our Experience in Banking and Financial Services
Our Experience in Banking and Financial ServicesOur Experience in Banking and Financial Services
Our Experience in Banking and Financial ServicesXebia IT Architects
 
Thought Paper: Overview of Banking Applications
Thought Paper: Overview of Banking ApplicationsThought Paper: Overview of Banking Applications
Thought Paper: Overview of Banking ApplicationsInfosys Finacle
 
IS Audit and Internal Controls
IS Audit and Internal ControlsIS Audit and Internal Controls
IS Audit and Internal ControlsBharath Rao
 
Bank audit slideshare
Bank audit   slideshareBank audit   slideshare
Bank audit slidesharePriti Parab
 

Viewers also liked (6)

Banking application & software solutions at competitive rate
Banking application & software solutions at competitive rateBanking application & software solutions at competitive rate
Banking application & software solutions at competitive rate
 
Our Experience in Banking and Financial Services
Our Experience in Banking and Financial ServicesOur Experience in Banking and Financial Services
Our Experience in Banking and Financial Services
 
Thought Paper: Overview of Banking Applications
Thought Paper: Overview of Banking ApplicationsThought Paper: Overview of Banking Applications
Thought Paper: Overview of Banking Applications
 
bankauditinITEnv
bankauditinITEnvbankauditinITEnv
bankauditinITEnv
 
IS Audit and Internal Controls
IS Audit and Internal ControlsIS Audit and Internal Controls
IS Audit and Internal Controls
 
Bank audit slideshare
Bank audit   slideshareBank audit   slideshare
Bank audit slideshare
 

Similar to Overview Of Lift Framework

Lift 2 0
Lift 2 0Lift 2 0
Lift 2 0SO
 
J query b_dotnet_ug_meet_12_may_2012
J query b_dotnet_ug_meet_12_may_2012J query b_dotnet_ug_meet_12_may_2012
J query b_dotnet_ug_meet_12_may_2012ghnash
 
Html5 and web technology update
Html5 and web technology updateHtml5 and web technology update
Html5 and web technology updateDoug Domeny
 
Writing HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAEWriting HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAERon Reiter
 
Rich Portlet Development in uPortal
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortalJennifer Bourey
 
Web Components With Rails
Web Components With RailsWeb Components With Rails
Web Components With RailsBoris Nadion
 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09Daniel Bryant
 
Android development with Scala and SBT
Android development with Scala and SBTAndroid development with Scala and SBT
Android development with Scala and SBTAnton Yalyshev
 
London Scala UG - Lift:Getting started with Scala
London Scala UG - Lift:Getting started with ScalaLondon Scala UG - Lift:Getting started with Scala
London Scala UG - Lift:Getting started with ScalaSkills Matter
 
Rails vs Web2py
Rails vs Web2pyRails vs Web2py
Rails vs Web2pyjonromero
 
A full introductory guide to React
A full introductory guide to ReactA full introductory guide to React
A full introductory guide to ReactJean Carlo Emer
 

Similar to Overview Of Lift Framework (20)

Lift 2 0
Lift 2 0Lift 2 0
Lift 2 0
 
Html5 For Jjugccc2009fall
Html5 For Jjugccc2009fallHtml5 For Jjugccc2009fall
Html5 For Jjugccc2009fall
 
J query b_dotnet_ug_meet_12_may_2012
J query b_dotnet_ug_meet_12_may_2012J query b_dotnet_ug_meet_12_may_2012
J query b_dotnet_ug_meet_12_may_2012
 
Play!ng with scala
Play!ng with scalaPlay!ng with scala
Play!ng with scala
 
Html5 and web technology update
Html5 and web technology updateHtml5 and web technology update
Html5 and web technology update
 
Writing HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAEWriting HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAE
 
Rich Portlet Development in uPortal
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortal
 
React js
React jsReact js
React js
 
Google app engine by example
Google app engine by exampleGoogle app engine by example
Google app engine by example
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
 
Web Components With Rails
Web Components With RailsWeb Components With Rails
Web Components With Rails
 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
 
Android development with Scala and SBT
Android development with Scala and SBTAndroid development with Scala and SBT
Android development with Scala and SBT
 
Jsf
JsfJsf
Jsf
 
Scala & Lift (JEEConf 2012)
Scala & Lift (JEEConf 2012)Scala & Lift (JEEConf 2012)
Scala & Lift (JEEConf 2012)
 
London Scala UG - Lift:Getting started with Scala
London Scala UG - Lift:Getting started with ScalaLondon Scala UG - Lift:Getting started with Scala
London Scala UG - Lift:Getting started with Scala
 
Rails vs Web2py
Rails vs Web2pyRails vs Web2py
Rails vs Web2py
 
A full introductory guide to React
A full introductory guide to ReactA full introductory guide to React
A full introductory guide to React
 
JSF 2.0 Preview
JSF 2.0 PreviewJSF 2.0 Preview
JSF 2.0 Preview
 
jQuery
jQueryjQuery
jQuery
 

More from Xebia IT Architects

Using Graph Databases For Insights Into Connected Data.
Using Graph Databases For Insights Into Connected Data.Using Graph Databases For Insights Into Connected Data.
Using Graph Databases For Insights Into Connected Data.Xebia IT Architects
 
Use Cases of #Grails in #WebApplications
Use Cases of #Grails in #WebApplicationsUse Cases of #Grails in #WebApplications
Use Cases of #Grails in #WebApplicationsXebia IT Architects
 
When elephants dance , enterprise goes mobile !
When elephants dance , enterprise goes mobile !When elephants dance , enterprise goes mobile !
When elephants dance , enterprise goes mobile !Xebia IT Architects
 
Exploiting vulnerabilities in location based commerce
Exploiting vulnerabilities in location based commerceExploiting vulnerabilities in location based commerce
Exploiting vulnerabilities in location based commerceXebia IT Architects
 
Modelling RESTful applications – Why should I not use verbs in REST url
Modelling RESTful applications – Why should I not use verbs in REST urlModelling RESTful applications – Why should I not use verbs in REST url
Modelling RESTful applications – Why should I not use verbs in REST urlXebia IT Architects
 
Scrumban - benefits of both the worlds
Scrumban - benefits of both the worldsScrumban - benefits of both the worlds
Scrumban - benefits of both the worldsXebia IT Architects
 
#Continuous delivery with #Deployit
#Continuous delivery with #Deployit#Continuous delivery with #Deployit
#Continuous delivery with #DeployitXebia IT Architects
 
Continuous integration using thucydides(bdd) with selenium
Continuous integration using thucydides(bdd) with seleniumContinuous integration using thucydides(bdd) with selenium
Continuous integration using thucydides(bdd) with seleniumXebia IT Architects
 
Xebia-Agile consulting and training offerings
Xebia-Agile consulting and training offeringsXebia-Agile consulting and training offerings
Xebia-Agile consulting and training offeringsXebia IT Architects
 
Xebia e-Commerce / mCommerce Solutions
Xebia e-Commerce / mCommerce SolutionsXebia e-Commerce / mCommerce Solutions
Xebia e-Commerce / mCommerce SolutionsXebia IT Architects
 
A warm and prosperous Happy Diwali to all our clients
A warm and prosperous Happy Diwali to all our clientsA warm and prosperous Happy Diwali to all our clients
A warm and prosperous Happy Diwali to all our clientsXebia IT Architects
 
"We Plan to double our headcount" - MD, Xebia India
"We Plan to double our headcount" - MD, Xebia India"We Plan to double our headcount" - MD, Xebia India
"We Plan to double our headcount" - MD, Xebia IndiaXebia IT Architects
 
Agile FAQs by Shrikant Vashishtha
Agile FAQs by Shrikant VashishthaAgile FAQs by Shrikant Vashishtha
Agile FAQs by Shrikant VashishthaXebia IT Architects
 
Agile Team Dynamics by Bhavin Chandulal Javia
Agile Team Dynamics by Bhavin Chandulal JaviaAgile Team Dynamics by Bhavin Chandulal Javia
Agile Team Dynamics by Bhavin Chandulal JaviaXebia IT Architects
 
Practicing Agile in Offshore Environment by Himanshu Seth & Imran Mir
Practicing Agile in Offshore Environment by Himanshu Seth & Imran MirPracticing Agile in Offshore Environment by Himanshu Seth & Imran Mir
Practicing Agile in Offshore Environment by Himanshu Seth & Imran MirXebia IT Architects
 

More from Xebia IT Architects (20)

Using Graph Databases For Insights Into Connected Data.
Using Graph Databases For Insights Into Connected Data.Using Graph Databases For Insights Into Connected Data.
Using Graph Databases For Insights Into Connected Data.
 
Use Cases of #Grails in #WebApplications
Use Cases of #Grails in #WebApplicationsUse Cases of #Grails in #WebApplications
Use Cases of #Grails in #WebApplications
 
When elephants dance , enterprise goes mobile !
When elephants dance , enterprise goes mobile !When elephants dance , enterprise goes mobile !
When elephants dance , enterprise goes mobile !
 
DevOps demystified
DevOps demystifiedDevOps demystified
DevOps demystified
 
Exploiting vulnerabilities in location based commerce
Exploiting vulnerabilities in location based commerceExploiting vulnerabilities in location based commerce
Exploiting vulnerabilities in location based commerce
 
Modelling RESTful applications – Why should I not use verbs in REST url
Modelling RESTful applications – Why should I not use verbs in REST urlModelling RESTful applications – Why should I not use verbs in REST url
Modelling RESTful applications – Why should I not use verbs in REST url
 
Scrumban - benefits of both the worlds
Scrumban - benefits of both the worldsScrumban - benefits of both the worlds
Scrumban - benefits of both the worlds
 
#Continuous delivery with #Deployit
#Continuous delivery with #Deployit#Continuous delivery with #Deployit
#Continuous delivery with #Deployit
 
Continuous integration using thucydides(bdd) with selenium
Continuous integration using thucydides(bdd) with seleniumContinuous integration using thucydides(bdd) with selenium
Continuous integration using thucydides(bdd) with selenium
 
Battlefield agility
Battlefield agilityBattlefield agility
Battlefield agility
 
Fish!ing for agile teams
Fish!ing for agile teamsFish!ing for agile teams
Fish!ing for agile teams
 
Xebia-Agile consulting and training offerings
Xebia-Agile consulting and training offeringsXebia-Agile consulting and training offerings
Xebia-Agile consulting and training offerings
 
Xebia e-Commerce / mCommerce Solutions
Xebia e-Commerce / mCommerce SolutionsXebia e-Commerce / mCommerce Solutions
Xebia e-Commerce / mCommerce Solutions
 
Growth at Xebia
Growth at XebiaGrowth at Xebia
Growth at Xebia
 
A warm and prosperous Happy Diwali to all our clients
A warm and prosperous Happy Diwali to all our clientsA warm and prosperous Happy Diwali to all our clients
A warm and prosperous Happy Diwali to all our clients
 
"We Plan to double our headcount" - MD, Xebia India
"We Plan to double our headcount" - MD, Xebia India"We Plan to double our headcount" - MD, Xebia India
"We Plan to double our headcount" - MD, Xebia India
 
Agile 2.0 - Our Road to Mastery
Agile 2.0 - Our Road to MasteryAgile 2.0 - Our Road to Mastery
Agile 2.0 - Our Road to Mastery
 
Agile FAQs by Shrikant Vashishtha
Agile FAQs by Shrikant VashishthaAgile FAQs by Shrikant Vashishtha
Agile FAQs by Shrikant Vashishtha
 
Agile Team Dynamics by Bhavin Chandulal Javia
Agile Team Dynamics by Bhavin Chandulal JaviaAgile Team Dynamics by Bhavin Chandulal Javia
Agile Team Dynamics by Bhavin Chandulal Javia
 
Practicing Agile in Offshore Environment by Himanshu Seth & Imran Mir
Practicing Agile in Offshore Environment by Himanshu Seth & Imran MirPracticing Agile in Offshore Environment by Himanshu Seth & Imran Mir
Practicing Agile in Offshore Environment by Himanshu Seth & Imran Mir
 

Recently uploaded

Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 

Recently uploaded (20)

Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 

Overview Of Lift Framework

  • 1. Overview of Lift Web Framework Vikas Hazrati www.xebiaindia.com
  • 2. Today There is a Wide Choice of Web Frameworks
  • 3. As Developers It is Hard to Make a Choice
  • 4. Every Framework Has its Own Set of Pitfalls
  • 5. But Quick Development is Still an Option
  • 6.
  • 7. Why is Lift Better? Convention over configuration Clean separation of presentation content and logic Leverage the Responsive Scala programming language community Concise code increases Powerful AJAX & Comet productivity Support Highly Scalable
  • 8. mvn archetype:generate -U -DarchetypeGroupId=net.liftweb -DarchetypeArtifactId=lift-archetype-blank -DarchetypeVersion=1.0 -DremoteRepositories=http://scala-tools.org/repo- releases -DgroupId=demo.helloworld -DartifactId=helloworld -Dversion=1.0-SNAPSHOT cd helloworld mvn jetty:run
  • 9.
  • 10. index.html <lift:surround with="default" at="content"> <h2>Welcome to your project!</h2> <p><lift:helloWorld.howdy /></p> </lift:surround> class HelloWorld { def howdy = <span>Welcome to helloworld at {new _root_.java.util.Date}</span> }
  • 11. default.html <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>
  • 12. Boot Class package bootstrap.liftweb import _root_.net.liftweb.util._ import _root_.net.liftweb.http._ import _root_.net.liftweb.sitemap._ import _root_.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:_*)) } }
  • 13. Lift Entry Point <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <filter> <filter-name>LiftFilter</filter-name> <display-name>Lift Filter</display-name> <description>The Filter that intercepts lift calls</description> <filter-class>net.liftweb.http.LiftFilter</filter-class> </filter> <filter-mapping> <filter-name>LiftFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
  • 14. Lift’s Main Objects net.liftweb.http.S net.liftweb.http.SHtml net.liftweb.http.LiftRules
  • 15. Template Snippets Boot Adding AJAX class Spice Model
  • 16. Model
  • 17. Maps to rdbms class ToDo extends LongKeyedMapper[ToDo] with IdPK { def getSingleton = ToDo object done extends MappedBoolean(this) object owner extends MappedLongForeignKey(this, User) object priority extends MappedInt(this) { override def defaultValue = 5 } object desc extends MappedPoliteString(this, 128) } object ToDo extends ToDo with LongKeyedMetaMapper[ToDo] Provides meta functionality Like finders etc
  • 19. Mapper and Record Frameworks Per instance Mapper Global MetaMapper Record Per field MappedField <project ...> ... <dependencies> ... <dependency> <groupId>net.liftweb</groupId> <artifactId>lift-mapper</artifactId> <version>1.0</version> <!-- or 1.1-SNAPSHOT, etc --> </dependency> </dependencies> ... </project>
  • 20. Database Connection class Boot { def boot { ... DB.defineConnectionManager(DefaultConnectionIdentifier, DBVendor) Schemifier.schemify(true, Log.infoF _, User, ToDo) import _root_.net.liftweb.mapper._ import _root_.java.sql._ object DBVendor extends ConnectionManager { // Force load the driver Class.forName("org.postgresql.Driver") // define methods def newConnection(name : ConnectionIdentifier) = { try { Full(DriverManager.getConnection( "jdbc:postgresql://localhost/mydatabase", "root", "secret")) } catch { case e : Exception => e.printStackTrace; Empty } } def releaseConnection (conn : Connection) { conn.close }
  • 21. import _root_.java.math.MathContext class Expense extends LongKeyedMapper[Expense] with IdPK { def getSingleton = Expense object dateOf extends MappedDateTime(this) object description extends MappedString(this,100) object amount extends MappedDecimal(this, MathContext.DECIMAL64, 2) object account extends MappedLongForeignKey(this, Account) } create save delete count countByInsecureSQL findAll findAllByInsecureSQL findAllByPreparedStatement findAllFields
  • 23. Templates Lift tag <lift:surround with="default" at="content"> <head><title>Hello!</title></head> <lift:Hello.world /> </lift:surround> Snippet
  • 24. Views class ExpenseView extends LiftView { override def dispatch = { case "enumerate" => doEnumerate _ } def doEnumerate () : NodeSeq = { ... <lift:surround with="default" at="content"> { expenseItems.toTable } </lift:surround> } }
  • 25. Tags <lift:snippet type="MyClass:render" /> snippet <lift:MyClass.render /> <lift:MyClass /> surround <lift:surround with="template_name" at=”binding”> children </lift:surround> <lift:bind name=”binding_name” /> bind <div class="accountUpdates"> < lift : comet type="AccountMonitor"> comet <ul><account:entries> <li><entry:time/> : <entry:user /> : <entry:amount /></li> </account:entries></ul> </ lift : comet> </div>
  • 26. Snippets View Logic
  • 27. <lift:Util.out> Lift tags Please Log In <b>Dude</b> </lift:Util.out> Corresponding Snippet package com.liftworkshop.snippet code import scala.xml.{NodeSeq} import com.liftworkshop._ import model._ class Util { def in(html: NodeSeq) = if (User.loggedIn_?) html else NodeSeq.Empty def out(html: NodeSeq) = if (!User.loggedIn_?) html else NodeSeq.Empty }
  • 28.
  • 29. Snippets class Ledger { def balance (content : NodeSeq) : NodeSeq = Text(currentLedger.formattedBalance) } class Ledger { def balance (content : NodeSeq) : NodeSeq = <p>{currentLedger.formattedBalance} as of <lift:Util.time /></p> } <lift:Ledger.balance> <ledger:balance/> as of <ledger:time /> </lift:Ledger.balance> class Ledger { def balance (content : NodeSeq ) : NodeSeq = bind ("ledger", content, "balance" -> Text(currentLedger.formattedBalance), "time" -> Text((new java.util.Date).toString)) }
  • 30. Snippets are Stateless Cookies SessionVar RequestVar StatefulSnippet Subclass
  • 32. Form Processing <html> ... <lift:Show.myForm form="POST"> <tr> <td>Name</td> <td><f:name><input type="text"/></f:name></td> </tr> <tr> <td>Birthyear</td> <td><f:year> <select><option>2007</option></select> </f:year></td> </tr> <tr> <td>&nbsp;</td> <td><input type="submit" value="Add"/></td> </tr> </lift:Show.myForm> </html>
  • 33. Form Processing class Show { def myForm(xhtml: NodeSeq) = { var name = "" def handleYear(year: String) { ... the form’s been submitted... do something } bind("f", xhtml, "name" -> text(name, name = _), "year" -> select((1900 to 2007). toList.map(_.toString). reverse.map(v => (v, v)), Empty, handleYear _)) } }
  • 34. Goodies ProtoUser and MegaProtoUser class User extends ProtoUser[User] { override def shortName = firstName.is override lastNameDisplayName = "surname" }
  • 36. JavaScript import JsCmds._ import JE._ var myName = "" bind(... "name" -> text(myName, myName = _, "id" -> "myName"), "submit" -> submit("Save", ..., "onclick" -> JsIf(JsEq(ValById("myName"), ""), Alert("You must provide a name") & JsReturn(false)) ) ) import net.liftweb.http.js.yui.YUIArtifacts class Boot { def boot = { ... LiftRules.jsArtifacts = YUIArtifacts ... }
  • 39. Comet Based on Scala Actors
  • 40. AJAX <lift:TD.list all_id="all_todos"> <div id="all_todos"> <div>Exclude done <todo:exclude/></div> <ul> <todo:list> <li> <todo:check><input type="checkbox"/></todo:check> <todo:priority> <select><option>1</option></select> </todo:priority> <todo:desc>To Do</todo:desc> </li> </todo:list> </ul> </div> </lift:TD.list>
  • 41. def list(html: NodeSeq) = { val id = S.attr("all_id").open_! def inner(): NodeSeq = { def reDraw() = SetHtml(id, inner()) bind("todo", html, "exclude" -> ajaxCheckbox(QueryNotDone, v => {QueryNotDone(v); reDraw}), "list" -> doList(reDraw) _) } inner() private def doList(reDraw: () => JsCmd)(html: NodeSeq): } NodeSeq = toShow. flatMap(td => bind("todo", html, "check" -> ajaxCheckbox(td.done, v => {td.done(v).save; reDraw()}), "priority" -> ajaxSelect(ToDo.priorityList, Full(td.priority.toString), v => {td.priority(v.toInt).save; reDraw()}), "desc" -> desc(td, reDraw) )) private def desc(td: ToDo, reDraw: () => JsCmd) = swappable(<span>{td.desc}</span>, <span>{ajaxText(td.desc, v => {td.desc(v).save; reDraw()})} </span>)
  • 42. Comet <lift:surround with="default" at="content"> <lift:comet type="Clock" name="Other"> Current Time: <clk:time>Missing Clock</clk:time> </lift:comet> </lift:surround> class Clock extends CometActor { override def defaultPrefix = Full("clk") def render = bind("time" -> timeSpan) def timeSpan = (<span id="time">{timeNow}</span>) // schedule a ping every 10 seconds so we redraw ActorPing.schedule(this, Tick, 10000L) override def lowPriority : PartialFunction[Any, Unit] = { case Tick => { println("Got tick " + new Date()); partialUpdate(SetHtml("time", Text(timeNow.toString))) // schedule an update in 10 seconds ActorPing.schedule(this, Tick, 10000L) } } } case object Tick
  • 44. Rails v/s Lift For single request processing, the lift code, running inside Tomcat, ran 4 times faster than the Rails code running inside Mongrel. However, the CPU utilization was less than 5% in the lift version, where it was 100% of 1 CPU (on a dual core machine) for the Rails version. For multiple simultaneous requests being made from multiple machines, we're seeing better than 20x performance of the lift code versus the Rails code with 5 Mongrel instances. Once again, the lift code is not using very much CPU and the Rails code is pegging both CPUs. http://lambda-the-ultimate.org/node/2147