Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play...

34
Getting started with Lift Richard Dallaway, @d6y [email protected]

Transcript of Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play...

Page 1: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

Getting started with LiftRichard Dallaway, @d6y

[email protected]

Page 2: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

lsug.org

Page 3: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞
Page 4: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

Struts

Grails

Rails

PHP

JSF

Wicket

GWT

JAX-RSStripes

Spring MVC

Play Seam

Seaside

Lift

Cocoon

WebObjects

Page 5: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

Struts

Grails

Rails

PHP

JSF

Wicket

GWT

JAX-RSStripes

Spring MVC

Play Seam

Seaside

Lift

Cocoon

WebObjects

Zero PlentyWeirdness

Page 6: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

☞☞☞

☞☞

http://liftweb.net

Page 7: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

Versions

1.0.3 Updated Jan 2010

2.0 M2 Released Feb 2010

both for Scala 2.7.7

Page 8: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞
Page 9: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞
Page 10: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

lift-base/lift-actorlift-base/lift-commonlift-base/lift-jsonlift-base/lift-utillift-base/lift-webkit

lift-modules/lift-amqplift-modules/lift-facebooklift-modules/lift-imaginglift-modules/lift-jtalift-modules/lift-ldaplift-modules/lift-machinelift-modules/lift-oauthlift-modules/lift-openidlift-modules/lift-osgi

lift-modules/lift-paypallift-modules/lift-testkitlift-modules/lift-textilelift-modules/lift-widgetslift-modules/lift-wizardlift-modules/lift-xmpp

lift-persistence/lift-couchdblift-persistence/lift-jpalift-persistence/lift-mapperlift-persistence/lift-record

$ find . -name lift\* -depth 2 -type d

Page 11: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

Agenda

• Part I: View first

• Part II: Doing stuff quickly

• Part III: Ajax

• Part IV: Real time web

Page 12: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

The time on this server is: Mon Mar 08 18:40:51 GMT 2010.

Page 13: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

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

Page 14: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

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> }

Page 15: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

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

Page 16: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

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) )

}}

Page 17: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞
Page 18: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

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

Page 19: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

package com.myprojects.snippet

import scala.xml.NodeSeqimport 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 ) )

) }

}

Page 20: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞
Page 21: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

$ 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):

Page 22: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

$ 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

Page 23: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

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] {}

Page 24: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

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

Page 25: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

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) ) } bind("directory", xhtml, ! ! "entry" -> Blog.findAll().flatMap(

b => <li>{b.url}</li> ), ! ! "new_blog" -> ajaxText("", add_new_blog _) ) } }

Page 26: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

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 _) ) }}

Page 27: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞
Page 28: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

Client

Server

Time

Browser UI

COMET Client

User Activity

Client Processing

Dis

play

Dis

play

Dis

play

Comet Event Bus

Initialization Dat

a P

ush

Dat

a P

ush

Dat

a P

ush

Dis

play

Dis

play

Dat

a P

ush

Dat

a P

ush

Server-Side Processing

Eve

nt

Eve

nt

Eve

nt

Eve

nt

Eve

nt

Page 29: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

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 _) )

Page 30: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

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))) } }

Page 31: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

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

Page 32: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

apress discount code

LONDONSCALAUQUCUAVGLT

Page 33: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞

Next Meeting

Traits & Mixins Kevin

Monday 12 April

Here, Skillsmatter

Page 34: Getting started with Lift · Struts Grails Rails PHP JSF Wicket GWT Stripes JAX-RS Spring MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness ☞ ☞ ☞ ☞ ☞