Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

London Scala UG - Lift:Getting started with Scala

5,424 views

Published on

Lift- Getting started with Scala

Published in: Technology, Business
  • You can also watch the related video here:

    http://skillsmatter.com/podcast/java-jee/lift-getting-started-with-scala-and-lift/rl-311
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

London Scala UG - Lift:Getting started with Scala

  1. 1. Getting started with Lift Richard Dallaway, @d6y richard@taykt.com
  2. 2. lsug.org
  3. 3. Struts Play GWT Seam Rails Spring MVC JSF WebObjects Grails PHP Cocoon Seaside Stripes JAX-RS Wicket Lift
  4. 4. Struts Play GWT Seam Rails Spring MVC JSF WebObjects Grails PHP Cocoon Seaside Stripes JAX-RS Wicket Lift Zero Plenty Weirdness
  5. 5. http://liftweb.net
  6. 6. Versions 1.0.3 Updated Jan 2010 2.0 M2 Released Feb 2010 both for Scala 2.7.7
  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
  8. 8. Agenda • Part I: View first • Part II: Doing stuff quickly • Part III: Ajax • Part IV: Real time web
  9. 9. The time on this server is: Mon Mar 08 18:40:51 GMT 2010.
  10. 10. <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>
  11. 11. 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> }
  12. 12. <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>
  13. 13. 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) ) } }
  14. 14. <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>
  15. 15. 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 ) ) ) } }
  16. 16. $ 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):
  17. 17. $ 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
  18. 18. 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] { }
  19. 19. <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>
  20. 20. 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 _) ) } }
  21. 21. 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 _) ) } }
  22. 22. 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
  23. 23. 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 _) )
  24. 24. 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))) } }
  25. 25. 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
  26. 26. apress discount code LONDONSCALAUQUCUAVGLT
  27. 27. Next Meeting Traits & Mixins Kevin Monday 12 April Here, Skillsmatter

×