Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Getting Started with Lift

Richard Dallaway
March 09, 2010
1

Getting Started with Lift

Talk at LSUG 9 March 2010

Richard Dallaway

March 09, 2010
Tweet

Transcript

  1. Struts Grails Rails PHP JSF Wicket GWT JAX-RS Stripes Spring

    MVC Play Seam Seaside Lift Cocoon WebObjects
  2. Struts Grails Rails PHP JSF Wicket GWT JAX-RS Stripes Spring

    MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness
  3. Agenda • Part I: View first • Part II: Doing

    stuff quickly • Part III: Ajax • Part IV: Real time web
  4. package com.myproject.snippetimport 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) ) }}
  5. package com.myprojects.snippetimport 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 ) ) ) } }
  6. $ 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):
  7. $ 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
  8. package com.brightonbloggers.admin.modelimport 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] {}
  9. package com.brightonbloggers.admin.snippetimport com.brightonbloggers.admin.model.Blogimport 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 _) ) } }
  10. package com.brightonbloggers.admin.snippetimport com.brightonbloggers.admin.model.Blogimport 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 _) ) }}
  11. 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 _) )
  12. package com.brightonbloggers.admin.cometimport 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))) } }
  13. 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