SlideShare a Scribd company logo
Getting started with Lift
       Richard Dallaway, @d6y
         richard@taykt.com
lsug.org
Struts       Play      GWT        Seam

 Rails    Spring MVC    JSF     WebObjects

Grails       PHP       Cocoon     Seaside

Stripes    JAX-RS      Wicket      Lift
Struts       Play        GWT       Seam

        Rails    Spring MVC      JSF    WebObjects

       Grails       PHP        Cocoon     Seaside

       Stripes    JAX-RS       Wicket      Lift

Zero                                                Plenty
                           Weirdness
http://liftweb.net
Versions

1.0.3   Updated Jan 2010

2.0 M2 Released Feb 2010


  both for Scala 2.7.7
$ find . -name lift* -depth 2 -type d

lift-base/lift-actor          lift-modules/lift-paypal
lift-base/lift-common         lift-modules/lift-testkit
lift-base/lift-json           lift-modules/lift-textile
lift-base/lift-util           lift-modules/lift-widgets
lift-base/lift-webkit         lift-modules/lift-wizard
                              lift-modules/lift-xmpp
lift-modules/lift-amqp
lift-modules/lift-facebook    lift-persistence/lift-couchdb
lift-modules/lift-imaging     lift-persistence/lift-jpa
lift-modules/lift-jta         lift-persistence/lift-mapper
lift-modules/lift-ldap        lift-persistence/lift-record
lift-modules/lift-machine
lift-modules/lift-oauth
lift-modules/lift-openid
lift-modules/lift-osgi
Agenda

• Part I: View first
• Part II: Doing stuff quickly
• Part III: Ajax
• Part IV: Real time web
The time on this server is: Mon Mar 08 18:40:51 GMT 2010.
<html xmlns="http://www.w3.org/1999/xhtml">
 <body>
   <h1>Hello world</h1>

  <p>The time on this server is:
       <lift:Time.now>
          time appears here
       </lift:Time.now>
  </p>

 </body>
</html>
package com.myproject.snippet

import scala.xml.NodeSeq

class Time {

    // My <lift:Time.now /> implementation:
    def now(xhtml: NodeSeq) =
        <span>{new java.util.Date()}</span>

}
<html xmlns="http://www.w3.org/1999/xhtml">
 <body>
   <h1>Hello world</h1>

  <lift:Time.now>
   <p>It’s <when:day/> at <when:hour/>.</p>
  </lift:Time.now>

 </body>
</html>
package com.myproject.snippet

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

class Time {

    def now(xhtml:NodeSeq) = {
      val day = "Monday"
      val hour = "7 o'clock"
      bind("when", xhtml,
       "hour" -> <span>{hour}</span>,
       "day" -> Text(day) )
    }
}
<html xmlns="http://www.w3.org/1999/xhtml">

<body>

<h1>Hello Canada</h1>

<lift:Olympics.results>
    <table>
        <table:rows>
        <tr>
             <td><r:country>Country here</r:country></td>
             <td><r:golds>Gold medal count</r:golds></td>
        </tr>
        </table:rows>
    </table>
</lift:Olympics.results>

</body>


</html>
package com.myprojects.snippet

import scala.xml.NodeSeq
import net.liftweb.util.Helpers._

class Olympics {

    case class Golds(country: String, medals: Int)

    def results(xhtml: NodeSeq) = {

        val vancouver = Golds("CAN", 14) :: Golds("GER", 10) ::
                        Golds("GBR", 1) :: Nil

        // <table:rows> <r:country/> <r:golds/> </table:rows>
        bind("table", xhtml,
        ! ! "rows" -> vancouver.flatMap( gold =>
                 bind("r", chooseTemplate("table", "rows", xhtml),
                       "country" -> gold.country,
                       "golds" -> gold.medals )
                 )
        )
    }

}
$ mvn archetype:generate 
 -DarchetypeCatalog=http://scala-tools.org/
Choose archetype:
1: http://scala-tools.org/ -> scala-archetype-simple (A simple scala project)
2: http://scala-tools.org/ -> lift-archetype-blank (A blank/empty liftweb project)
3: http://scala-tools.org/ -> lift-archetype-basic (A basic liftweb project (with DB, css, ...))
Choose a number: (1/2/3):
$ mvn archetype:generate 
 -DarchetypeGroupId=net.liftweb 
 -DarchetypeArtifactId=lift-archetype-blank 
 -DarchetypeVersion=2.0-M2 
 -DremoteRepositories=http://scala-tools.org/repo-releases 
 -DgroupId=com.example.proj
package com.brightonbloggers.admin.model

import   net.liftweb.common._
import   net.liftweb.util._
import   net.liftweb.mapper._
import   net.liftweb.http._

class Blog extends LongKeyedMapper[Blog] with IdPK {

  def getSingleton = Blog

  object title extends MappedString(this, 20)

  object url extends MappedString(this, 100) {
    override def validations = isUrl _ :: super.validations
  }

  def isUrl(u:String) = if (url startsWith "http")
!     ! !   !   !   !   !    Nil
!     ! !   !   !   !   else
!     ! !   !   !   !   !    List(FieldError(url, S.?("field.url.error")))
}

object Blog extends Blog with LongKeyedMetaMapper[Blog] with CRUDify[Long,Blog]
{
}
<lift:surround with="default" at="content">

    <h1>Ajax blog</h1>

    <div id="list">

    <lift:Blogs.list>

        <ul>
           <directory:entry />
        </ul>

        <directory:new_blog />

    </lift:Blogs.list>

    </div>

</lift:surround>
import com.brightonbloggers.admin.model.Blog

import     scala.xml._
import     net.liftweb.common._
import     net.liftweb.mapper._
import     net.liftweb.http.SHtml._
import     net.liftweb.http.js.JsCmds._
import     net.liftweb.util.Helpers._
import     net.liftweb.http.S._

class Blogs {

        def list(xhtml: NodeSeq): NodeSeq = {
!
        def add_new_blog(s: String) = {
          Blog.create.url(s).title(s).save
          SetHtml( "list", list(xhtml) )
        }

        bind("directory", xhtml,
        ! ! "entry" -> Blog.findAll().flatMap(
                               b => <li>{b.url}</li> ),
        ! ! "new_blog" -> ajaxText("", add_new_blog _)
        )

    }

}
package com.brightonbloggers.admin.snippet

import com.brightonbloggers.admin.model.Blog

import     scala.xml._
import     net.liftweb.common._
import     net.liftweb.mapper._
import     net.liftweb.http.SHtml._
import     net.liftweb.http.js.JsCmds._
import     net.liftweb.util.Helpers._
import     net.liftweb.http.S._

class Blogs {

    def list(xhtml: NodeSeq): NodeSeq = {
!
        def add_new_blog(s: String) = {
          Blog.create.url(s).title(s).save
          SetHtml("list", list(xhtml) )
        }

        def update_blog(blog: Blog)(new_value: String) = {
           blog.url(new_value).save
           SetHtml("list", list(xhtml) )
        }

        def click_to_edit(blog: Blog) : NodeSeq =
        !!   swappable( <li>{blog.url}</li>,
        !!   !           ajaxText(blog.url, update_blog(blog) _ ) )

        bind("directory", xhtml,
        !!   "entry" -> Blog.findAll().flatMap( click_to_edit _ ),
        !!   "new_blog" -> ajaxText("", add_new_blog _)
        )

    }
}
User Activity




                                                                    Client Processing




                                 Comet Event Bus
                         Event
                                                   Initialization

                                                   Data Push
                         Event                                                          Displa
                                                                                               y
                                                   Data Push
                                                                                        Displa
                                                                                               y



                         Event
                                                   Data Push
                         Event                                                          Displa
                                                                                               y
                                                   Data Push
                                                                                        Displa
                                                                                               y


                         Event
                                                   Data Push
Server-Side Processing


                                                                                        Displa
                                                                                               y
def list(xhtml: NodeSeq): NodeSeq = {
!
     def countable(blog: Blog) : NodeSeq =
     !    <li>{link("/static/list",
            () => { StatsServer ! blog },
             Text(blog.url)) }</li>

     bind("directory", xhtml,
     ! ! "entry" -> Blog.findAll().flatMap(countable _)
     )
package com.brightonbloggers.admin.comet

import   net.liftweb.http._
import   net.liftweb.common._
import   net.liftweb.util.Helpers._
import   net.liftweb.http.js._
import   net.liftweb.actor._
import   net.liftweb.http.js.JsCmds._
import   scala.xml._

object StatsServer extends LiftActor with ListenerManager {

    var count = 0

    override def lowPriority = {
      case b =>
        count = count + 1
        updateListeners()
    }

    def createUpdate = count
}


// <lift:comet type=”StatsWatch” />
class StatsWatch extends CometActor with CometListenee {

    def registerWith = StatsServer

    override def render = <div id="total">0</div>

    override def lowPriority = {
      case count: Int =>
        partialUpdate(SetHtml("total", Text(count.toString)))
    }

}
Thank you.
• Lift book: http://groups.google.com/group/
  the-lift-book
• Liftweb.net: Wiki, mailing list, getting started
  guide
• Visit lsug.org, join the meetup.com group
apress discount code

 LONDONSCALAUQUCUAVGLT
Next Meeting

 Traits & Mixins
 Kevin
 Monday 12 April
 Here, Skillsmatter
London Scala UG - Lift:Getting started with Scala

More Related Content

Viewers also liked

Joe Baguley Cloud Camp London7 Ppt
Joe Baguley Cloud Camp London7 PptJoe Baguley Cloud Camp London7 Ppt
Joe Baguley Cloud Camp London7 Ppt
Skills Matter
 
Building mobile web application with Grails, by Sebastien Blanc, presented at...
Building mobile web application with Grails, by Sebastien Blanc, presented at...Building mobile web application with Grails, by Sebastien Blanc, presented at...
Building mobile web application with Grails, by Sebastien Blanc, presented at...
Skills Matter
 
Databases -- Have it Your Way (Frederick Cheung)
Databases -- Have it Your Way (Frederick Cheung)Databases -- Have it Your Way (Frederick Cheung)
Databases -- Have it Your Way (Frederick Cheung)
Skills Matter
 
Daniel Sikar Amazon Ec2 S3
Daniel Sikar Amazon Ec2 S3Daniel Sikar Amazon Ec2 S3
Daniel Sikar Amazon Ec2 S3Skills Matter
 
Uncertainty in agile projects
Uncertainty in agile projectsUncertainty in agile projects
Uncertainty in agile projectsSkills Matter
 
Why Cqrs
Why CqrsWhy Cqrs
Why Cqrs
Skills Matter
 
Betting On Data Grids
Betting On Data GridsBetting On Data Grids
Betting On Data GridsSkills Matter
 
Journey To Systemic Improvement Lean Exchange Dec 2009 David J
Journey To Systemic Improvement Lean Exchange Dec 2009 David JJourney To Systemic Improvement Lean Exchange Dec 2009 David J
Journey To Systemic Improvement Lean Exchange Dec 2009 David J
Skills Matter
 
Developing and Deploying Java applications on the Amazon Elastic Compute Clou...
Developing and Deploying Java applications on the Amazon Elastic Compute Clou...Developing and Deploying Java applications on the Amazon Elastic Compute Clou...
Developing and Deploying Java applications on the Amazon Elastic Compute Clou...
Chris Richardson
 
Seth Edwards on MongoDB
Seth Edwards on MongoDBSeth Edwards on MongoDB
Seth Edwards on MongoDB
Skills Matter
 
Command Query Responsibility Segregation
Command Query Responsibility SegregationCommand Query Responsibility Segregation
Command Query Responsibility Segregation
Skills Matter
 
Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen LjuSkills Matter
 
Auto-Scaling Web Application Security in Amazon Web Services (SEC308) | AWS r...
Auto-Scaling Web Application Security in Amazon Web Services (SEC308) | AWS r...Auto-Scaling Web Application Security in Amazon Web Services (SEC308) | AWS r...
Auto-Scaling Web Application Security in Amazon Web Services (SEC308) | AWS r...
Amazon Web Services
 

Viewers also liked (13)

Joe Baguley Cloud Camp London7 Ppt
Joe Baguley Cloud Camp London7 PptJoe Baguley Cloud Camp London7 Ppt
Joe Baguley Cloud Camp London7 Ppt
 
Building mobile web application with Grails, by Sebastien Blanc, presented at...
Building mobile web application with Grails, by Sebastien Blanc, presented at...Building mobile web application with Grails, by Sebastien Blanc, presented at...
Building mobile web application with Grails, by Sebastien Blanc, presented at...
 
Databases -- Have it Your Way (Frederick Cheung)
Databases -- Have it Your Way (Frederick Cheung)Databases -- Have it Your Way (Frederick Cheung)
Databases -- Have it Your Way (Frederick Cheung)
 
Daniel Sikar Amazon Ec2 S3
Daniel Sikar Amazon Ec2 S3Daniel Sikar Amazon Ec2 S3
Daniel Sikar Amazon Ec2 S3
 
Uncertainty in agile projects
Uncertainty in agile projectsUncertainty in agile projects
Uncertainty in agile projects
 
Why Cqrs
Why CqrsWhy Cqrs
Why Cqrs
 
Betting On Data Grids
Betting On Data GridsBetting On Data Grids
Betting On Data Grids
 
Journey To Systemic Improvement Lean Exchange Dec 2009 David J
Journey To Systemic Improvement Lean Exchange Dec 2009 David JJourney To Systemic Improvement Lean Exchange Dec 2009 David J
Journey To Systemic Improvement Lean Exchange Dec 2009 David J
 
Developing and Deploying Java applications on the Amazon Elastic Compute Clou...
Developing and Deploying Java applications on the Amazon Elastic Compute Clou...Developing and Deploying Java applications on the Amazon Elastic Compute Clou...
Developing and Deploying Java applications on the Amazon Elastic Compute Clou...
 
Seth Edwards on MongoDB
Seth Edwards on MongoDBSeth Edwards on MongoDB
Seth Edwards on MongoDB
 
Command Query Responsibility Segregation
Command Query Responsibility SegregationCommand Query Responsibility Segregation
Command Query Responsibility Segregation
 
Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen Lju
 
Auto-Scaling Web Application Security in Amazon Web Services (SEC308) | AWS r...
Auto-Scaling Web Application Security in Amazon Web Services (SEC308) | AWS r...Auto-Scaling Web Application Security in Amazon Web Services (SEC308) | AWS r...
Auto-Scaling Web Application Security in Amazon Web Services (SEC308) | AWS r...
 

Similar to London Scala UG - Lift:Getting started with Scala

Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Frameworkvhazrati
 
Engage 2013 - Why Upgrade to v10 Tag
Engage 2013 - Why Upgrade to v10 TagEngage 2013 - Why Upgrade to v10 Tag
Engage 2013 - Why Upgrade to v10 TagWebtrends
 
Lift 2 0
Lift 2 0Lift 2 0
Lift 2 0SO
 
Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of usOSCON Byrum
 
Engage 2013 - Multi Channel Data Collection
Engage 2013 - Multi Channel Data CollectionEngage 2013 - Multi Channel Data Collection
Engage 2013 - Multi Channel Data CollectionWebtrends
 
Serverless Java on Kubernetes
Serverless Java on KubernetesServerless Java on Kubernetes
Serverless Java on Kubernetes
Krzysztof Sobkowiak
 
Implementing and Visualizing Clickstream data with MongoDB
Implementing and Visualizing Clickstream data with MongoDBImplementing and Visualizing Clickstream data with MongoDB
Implementing and Visualizing Clickstream data with MongoDB
MongoDB
 
Single page webapps & javascript-testing
Single page webapps & javascript-testingSingle page webapps & javascript-testing
Single page webapps & javascript-testing
smontanari
 
Event Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BEEvent Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BE
Andrzej Ludwikowski
 
混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaver混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaveryangdj
 
After max+phonegap
After max+phonegapAfter max+phonegap
After max+phonegapyangdj
 
Everything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the WebEverything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the Web
James Rakich
 
JavaScript para Graficos y Visualizacion de Datos - BogotaJS
JavaScript para Graficos y Visualizacion de Datos - BogotaJSJavaScript para Graficos y Visualizacion de Datos - BogotaJS
JavaScript para Graficos y Visualizacion de Datos - BogotaJSphilogb
 
JavaScript para Graficos y Visualizacion de Datos
JavaScript para Graficos y Visualizacion de DatosJavaScript para Graficos y Visualizacion de Datos
JavaScript para Graficos y Visualizacion de Datosphilogb
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
pootsbook
 
Whats New for WPF in .NET 4.5
Whats New for WPF in .NET 4.5Whats New for WPF in .NET 4.5
Whats New for WPF in .NET 4.5
Rainer Stropek
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
Vadym Khondar
 
Data visualization in python/Django
Data visualization in python/DjangoData visualization in python/Django
Data visualization in python/Django
kenluck2001
 
Integrate Solr with real-time stream processing applications
Integrate Solr with real-time stream processing applicationsIntegrate Solr with real-time stream processing applications
Integrate Solr with real-time stream processing applications
lucenerevolution
 

Similar to London Scala UG - Lift:Getting started with Scala (20)

Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Framework
 
Engage 2013 - Why Upgrade to v10 Tag
Engage 2013 - Why Upgrade to v10 TagEngage 2013 - Why Upgrade to v10 Tag
Engage 2013 - Why Upgrade to v10 Tag
 
Lift 2 0
Lift 2 0Lift 2 0
Lift 2 0
 
Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of us
 
Engage 2013 - Multi Channel Data Collection
Engage 2013 - Multi Channel Data CollectionEngage 2013 - Multi Channel Data Collection
Engage 2013 - Multi Channel Data Collection
 
Serverless Java on Kubernetes
Serverless Java on KubernetesServerless Java on Kubernetes
Serverless Java on Kubernetes
 
Implementing and Visualizing Clickstream data with MongoDB
Implementing and Visualizing Clickstream data with MongoDBImplementing and Visualizing Clickstream data with MongoDB
Implementing and Visualizing Clickstream data with MongoDB
 
Single page webapps & javascript-testing
Single page webapps & javascript-testingSingle page webapps & javascript-testing
Single page webapps & javascript-testing
 
Event Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BEEvent Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Devoxx BE
 
Ajax-Tutorial
Ajax-TutorialAjax-Tutorial
Ajax-Tutorial
 
混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaver混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaver
 
After max+phonegap
After max+phonegapAfter max+phonegap
After max+phonegap
 
Everything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the WebEverything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the Web
 
JavaScript para Graficos y Visualizacion de Datos - BogotaJS
JavaScript para Graficos y Visualizacion de Datos - BogotaJSJavaScript para Graficos y Visualizacion de Datos - BogotaJS
JavaScript para Graficos y Visualizacion de Datos - BogotaJS
 
JavaScript para Graficos y Visualizacion de Datos
JavaScript para Graficos y Visualizacion de DatosJavaScript para Graficos y Visualizacion de Datos
JavaScript para Graficos y Visualizacion de Datos
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
Whats New for WPF in .NET 4.5
Whats New for WPF in .NET 4.5Whats New for WPF in .NET 4.5
Whats New for WPF in .NET 4.5
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
 
Data visualization in python/Django
Data visualization in python/DjangoData visualization in python/Django
Data visualization in python/Django
 
Integrate Solr with real-time stream processing applications
Integrate Solr with real-time stream processing applicationsIntegrate Solr with real-time stream processing applications
Integrate Solr with real-time stream processing applications
 

More from Skills Matter

5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence
Skills Matter
 
Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applications
Skills Matter
 
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvmScala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Skills Matter
 
Oscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimOscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimSkills Matter
 
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Skills Matter
 
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlCukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Skills Matter
 
Cukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.jsCukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.js
Skills Matter
 
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Skills Matter
 
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Skills Matter
 
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source worldProgressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Skills Matter
 
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Skills Matter
 
Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#
Skills Matter
 
A poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testingA poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testing
Skills Matter
 
Russ miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveRuss miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveSkills Matter
 
Simon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSimon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelism
Skills Matter
 
I went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tI went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tSkills Matter
 

More from Skills Matter (20)

5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence
 
Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applications
 
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvmScala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
 
Oscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimOscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheim
 
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
 
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlCukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberl
 
Cukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.jsCukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.js
 
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
 
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
 
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source worldProgressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source world
 
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
 
Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#
 
A poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testingA poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testing
 
Russ miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveRuss miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-dive
 
Serendipity-neo4j
Serendipity-neo4jSerendipity-neo4j
Serendipity-neo4j
 
Simon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSimon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelism
 
Plug 20110217
Plug   20110217Plug   20110217
Plug 20110217
 
Lug presentation
Lug presentationLug presentation
Lug presentation
 
I went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tI went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_t
 
Plug saiku
Plug   saikuPlug   saiku
Plug saiku
 

Recently uploaded

The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
SOFTTECHHUB
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
Matthew Sinclair
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
James Anderson
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
nkrafacyberclub
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Aggregage
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
Neo4j
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
Pierluigi Pugliese
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
Peter Spielvogel
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
DianaGray10
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
Neo4j
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
Neo4j
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 

Recently uploaded (20)

The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
GraphSummit Singapore | Graphing Success: Revolutionising Organisational Stru...
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 

London Scala UG - Lift:Getting started with Scala

  • 1. Getting started with Lift Richard Dallaway, @d6y richard@taykt.com
  • 3.
  • 4. Struts Play GWT Seam Rails Spring MVC JSF WebObjects Grails PHP Cocoon Seaside Stripes JAX-RS Wicket Lift
  • 5. Struts Play GWT Seam Rails Spring MVC JSF WebObjects Grails PHP Cocoon Seaside Stripes JAX-RS Wicket Lift Zero Plenty Weirdness
  • 7. Versions 1.0.3 Updated Jan 2010 2.0 M2 Released Feb 2010 both for Scala 2.7.7
  • 8.
  • 9.
  • 10. $ find . -name lift* -depth 2 -type d lift-base/lift-actor lift-modules/lift-paypal lift-base/lift-common lift-modules/lift-testkit lift-base/lift-json lift-modules/lift-textile lift-base/lift-util lift-modules/lift-widgets lift-base/lift-webkit lift-modules/lift-wizard lift-modules/lift-xmpp lift-modules/lift-amqp lift-modules/lift-facebook lift-persistence/lift-couchdb lift-modules/lift-imaging lift-persistence/lift-jpa lift-modules/lift-jta lift-persistence/lift-mapper lift-modules/lift-ldap lift-persistence/lift-record lift-modules/lift-machine lift-modules/lift-oauth lift-modules/lift-openid lift-modules/lift-osgi
  • 11. Agenda • Part I: View first • Part II: Doing stuff quickly • Part III: Ajax • Part IV: Real time web
  • 12. The time on this server is: Mon Mar 08 18:40:51 GMT 2010.
  • 13. <html xmlns="http://www.w3.org/1999/xhtml"> <body> <h1>Hello world</h1> <p>The time on this server is: <lift:Time.now> time appears here </lift:Time.now> </p> </body> </html>
  • 14. package com.myproject.snippet import scala.xml.NodeSeq class Time { // My <lift:Time.now /> implementation: def now(xhtml: NodeSeq) = <span>{new java.util.Date()}</span> }
  • 15. <html xmlns="http://www.w3.org/1999/xhtml"> <body> <h1>Hello world</h1> <lift:Time.now> <p>It’s <when:day/> at <when:hour/>.</p> </lift:Time.now> </body> </html>
  • 16. package com.myproject.snippet import scala.xml.{NodeSeq,Text} import net.liftweb.util.Helpers._ class Time { def now(xhtml:NodeSeq) = { val day = "Monday" val hour = "7 o'clock" bind("when", xhtml, "hour" -> <span>{hour}</span>, "day" -> Text(day) ) } }
  • 17.
  • 18. <html xmlns="http://www.w3.org/1999/xhtml"> <body> <h1>Hello Canada</h1> <lift:Olympics.results> <table> <table:rows> <tr> <td><r:country>Country here</r:country></td> <td><r:golds>Gold medal count</r:golds></td> </tr> </table:rows> </table> </lift:Olympics.results> </body> </html>
  • 19. package com.myprojects.snippet import scala.xml.NodeSeq import net.liftweb.util.Helpers._ class Olympics { case class Golds(country: String, medals: Int) def results(xhtml: NodeSeq) = { val vancouver = Golds("CAN", 14) :: Golds("GER", 10) :: Golds("GBR", 1) :: Nil // <table:rows> <r:country/> <r:golds/> </table:rows> bind("table", xhtml, ! ! "rows" -> vancouver.flatMap( gold => bind("r", chooseTemplate("table", "rows", xhtml), "country" -> gold.country, "golds" -> gold.medals ) ) ) } }
  • 20.
  • 21. $ mvn archetype:generate -DarchetypeCatalog=http://scala-tools.org/ Choose archetype: 1: http://scala-tools.org/ -> scala-archetype-simple (A simple scala project) 2: http://scala-tools.org/ -> lift-archetype-blank (A blank/empty liftweb project) 3: http://scala-tools.org/ -> lift-archetype-basic (A basic liftweb project (with DB, css, ...)) Choose a number: (1/2/3):
  • 22. $ mvn archetype:generate -DarchetypeGroupId=net.liftweb -DarchetypeArtifactId=lift-archetype-blank -DarchetypeVersion=2.0-M2 -DremoteRepositories=http://scala-tools.org/repo-releases -DgroupId=com.example.proj
  • 23. package com.brightonbloggers.admin.model import net.liftweb.common._ import net.liftweb.util._ import net.liftweb.mapper._ import net.liftweb.http._ class Blog extends LongKeyedMapper[Blog] with IdPK { def getSingleton = Blog object title extends MappedString(this, 20) object url extends MappedString(this, 100) { override def validations = isUrl _ :: super.validations } def isUrl(u:String) = if (url startsWith "http") ! ! ! ! ! ! ! Nil ! ! ! ! ! ! else ! ! ! ! ! ! ! List(FieldError(url, S.?("field.url.error"))) } object Blog extends Blog with LongKeyedMetaMapper[Blog] with CRUDify[Long,Blog] { }
  • 24. <lift:surround with="default" at="content"> <h1>Ajax blog</h1> <div id="list"> <lift:Blogs.list> <ul> <directory:entry /> </ul> <directory:new_blog /> </lift:Blogs.list> </div> </lift:surround>
  • 25. import com.brightonbloggers.admin.model.Blog import scala.xml._ import net.liftweb.common._ import net.liftweb.mapper._ import net.liftweb.http.SHtml._ import net.liftweb.http.js.JsCmds._ import net.liftweb.util.Helpers._ import net.liftweb.http.S._ class Blogs { def list(xhtml: NodeSeq): NodeSeq = { ! def add_new_blog(s: String) = { Blog.create.url(s).title(s).save SetHtml( "list", list(xhtml) ) } bind("directory", xhtml, ! ! "entry" -> Blog.findAll().flatMap( b => <li>{b.url}</li> ), ! ! "new_blog" -> ajaxText("", add_new_blog _) ) } }
  • 26. package com.brightonbloggers.admin.snippet import com.brightonbloggers.admin.model.Blog import scala.xml._ import net.liftweb.common._ import net.liftweb.mapper._ import net.liftweb.http.SHtml._ import net.liftweb.http.js.JsCmds._ import net.liftweb.util.Helpers._ import net.liftweb.http.S._ class Blogs { def list(xhtml: NodeSeq): NodeSeq = { ! def add_new_blog(s: String) = { Blog.create.url(s).title(s).save SetHtml("list", list(xhtml) ) } def update_blog(blog: Blog)(new_value: String) = { blog.url(new_value).save SetHtml("list", list(xhtml) ) } def click_to_edit(blog: Blog) : NodeSeq = !! swappable( <li>{blog.url}</li>, !! ! ajaxText(blog.url, update_blog(blog) _ ) ) bind("directory", xhtml, !! "entry" -> Blog.findAll().flatMap( click_to_edit _ ), !! "new_blog" -> ajaxText("", add_new_blog _) ) } }
  • 27.
  • 28. User Activity Client Processing Comet Event Bus Event Initialization Data Push Event Displa y Data Push Displa y Event Data Push Event Displa y Data Push Displa y Event Data Push Server-Side Processing Displa y
  • 29. def list(xhtml: NodeSeq): NodeSeq = { ! def countable(blog: Blog) : NodeSeq = ! <li>{link("/static/list", () => { StatsServer ! blog }, Text(blog.url)) }</li> bind("directory", xhtml, ! ! "entry" -> Blog.findAll().flatMap(countable _) )
  • 30. package com.brightonbloggers.admin.comet import net.liftweb.http._ import net.liftweb.common._ import net.liftweb.util.Helpers._ import net.liftweb.http.js._ import net.liftweb.actor._ import net.liftweb.http.js.JsCmds._ import scala.xml._ object StatsServer extends LiftActor with ListenerManager { var count = 0 override def lowPriority = { case b => count = count + 1 updateListeners() } def createUpdate = count } // <lift:comet type=”StatsWatch” /> class StatsWatch extends CometActor with CometListenee { def registerWith = StatsServer override def render = <div id="total">0</div> override def lowPriority = { case count: Int => partialUpdate(SetHtml("total", Text(count.toString))) } }
  • 31. Thank you. • Lift book: http://groups.google.com/group/ the-lift-book • Liftweb.net: Wiki, mailing list, getting started guide • Visit lsug.org, join the meetup.com group
  • 32. apress discount code LONDONSCALAUQUCUAVGLT
  • 33. Next Meeting Traits & Mixins Kevin Monday 12 April Here, Skillsmatter