SlideShare a Scribd company logo
1 of 46
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
Scala based Lift Framework

More Related Content

What's hot

td_mxc_rubyrails_shin
td_mxc_rubyrails_shintd_mxc_rubyrails_shin
td_mxc_rubyrails_shin
tutorialsruby
 
Simplify AJAX using jQuery
Simplify AJAX using jQuerySimplify AJAX using jQuery
Simplify AJAX using jQuery
Siva Arunachalam
 
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
Jon Kruger
 
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
HUJAK - Hrvatska udruga Java korisnika / Croatian Java User Association
 

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
 
Unit Testing at Scale
Unit Testing at ScaleUnit Testing at Scale
Unit Testing at Scale
 
Node.js in action
Node.js in actionNode.js in action
Node.js in action
 
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

Composición fotográfica miguel
Composición fotográfica   miguelComposición fotográfica   miguel
Composición fotográfica miguel
Junio-maria
 
VALUATION OF OLD R.C.C. BUILDINGS
VALUATION OF OLD R.C.C. BUILDINGSVALUATION OF OLD R.C.C. BUILDINGS
VALUATION OF OLD R.C.C. BUILDINGS
Bangalore Property
 
The Whys, The Hows of Structural Audit of Buildings
The Whys, The Hows of Structural Audit of BuildingsThe Whys, The Hows of Structural Audit of Buildings
The Whys, The Hows of Structural Audit of Buildings
Renuka Consultants
 
IPR Protection for Hardware Startups - Patents, Trademarks, Copyrights and De...
IPR Protection for Hardware Startups - Patents, Trademarks, Copyrights and De...IPR Protection for Hardware Startups - Patents, Trademarks, Copyrights and De...
IPR Protection for Hardware Startups - Patents, Trademarks, Copyrights and De...
Rahul Dev
 
WP Management Reporting Excellence_3
WP Management Reporting Excellence_3WP Management Reporting Excellence_3
WP Management Reporting Excellence_3
Fabien Lennertz
 

Viewers also liked (18)

Abhishek resume4
Abhishek resume4Abhishek resume4
Abhishek resume4
 
Composición fotográfica miguel
Composición fotográfica   miguelComposición fotográfica   miguel
Composición fotográfica miguel
 
Management Information System- Information Technology Concepts
Management Information System-  Information Technology ConceptsManagement Information System-  Information Technology Concepts
Management Information System- Information Technology Concepts
 
Affordable Credit to Vulnerable Female Micro Entrepreneurs
Affordable Credit to Vulnerable Female Micro EntrepreneursAffordable Credit to Vulnerable Female Micro Entrepreneurs
Affordable Credit to Vulnerable Female Micro Entrepreneurs
 
Freedom of Expression and Trademark Rights in India
Freedom of Expression and Trademark Rights in IndiaFreedom of Expression and Trademark Rights in India
Freedom of Expression and Trademark Rights in India
 
VALUATION OF OLD R.C.C. BUILDINGS
VALUATION OF OLD R.C.C. BUILDINGSVALUATION OF OLD R.C.C. BUILDINGS
VALUATION OF OLD R.C.C. BUILDINGS
 
Using Pop Culture References in Advertisements? Just Do It Right | Orange Cou...
Using Pop Culture References in Advertisements? Just Do It Right | Orange Cou...Using Pop Culture References in Advertisements? Just Do It Right | Orange Cou...
Using Pop Culture References in Advertisements? Just Do It Right | Orange Cou...
 
PRINT JOURNALISM II- OBJECTIVES OF EDITING
 PRINT JOURNALISM II- OBJECTIVES OF EDITING PRINT JOURNALISM II- OBJECTIVES OF EDITING
PRINT JOURNALISM II- OBJECTIVES OF EDITING
 
International Patent Classification IPC for Performing Patent Infringement Se...
International Patent Classification IPC for Performing Patent Infringement Se...International Patent Classification IPC for Performing Patent Infringement Se...
International Patent Classification IPC for Performing Patent Infringement Se...
 
How Businesses can Navigate Indian Markets | Patent Amendment Rules 2016 | Cu...
How Businesses can Navigate Indian Markets | Patent Amendment Rules 2016 | Cu...How Businesses can Navigate Indian Markets | Patent Amendment Rules 2016 | Cu...
How Businesses can Navigate Indian Markets | Patent Amendment Rules 2016 | Cu...
 
The Whys, The Hows of Structural Audit of Buildings
The Whys, The Hows of Structural Audit of BuildingsThe Whys, The Hows of Structural Audit of Buildings
The Whys, The Hows of Structural Audit of Buildings
 
Pharmaceutical patents in india – compulsory licensing, health emergency & af...
Pharmaceutical patents in india – compulsory licensing, health emergency & af...Pharmaceutical patents in india – compulsory licensing, health emergency & af...
Pharmaceutical patents in india – compulsory licensing, health emergency & af...
 
Girish_BharadwajK_RESUME
Girish_BharadwajK_RESUMEGirish_BharadwajK_RESUME
Girish_BharadwajK_RESUME
 
The Drugs and Magic Remedies (Objectionable Advertisements) Act, 1954
The Drugs and Magic Remedies (Objectionable Advertisements) Act, 1954The Drugs and Magic Remedies (Objectionable Advertisements) Act, 1954
The Drugs and Magic Remedies (Objectionable Advertisements) Act, 1954
 
feasibility study Chapter 4
feasibility study Chapter 4feasibility study Chapter 4
feasibility study Chapter 4
 
Press council of India
Press council of IndiaPress council of India
Press council of India
 
IPR Protection for Hardware Startups - Patents, Trademarks, Copyrights and De...
IPR Protection for Hardware Startups - Patents, Trademarks, Copyrights and De...IPR Protection for Hardware Startups - Patents, Trademarks, Copyrights and De...
IPR Protection for Hardware Startups - Patents, Trademarks, Copyrights and De...
 
WP Management Reporting Excellence_3
WP Management Reporting Excellence_3WP Management Reporting Excellence_3
WP Management Reporting Excellence_3
 

Similar to Scala based Lift Framework

Lift 2 0
Lift 2 0Lift 2 0
Lift 2 0
SO
 

Similar to Scala based 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
 

Recently uploaded

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Recently uploaded (20)

Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 

Scala based 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