Peter Robinett [email protected] for DUSE VI, 2010-06-30

Peter Robinett Peter@Bubblefoundry.Com for DUSE VI, 2010-06-30

"' L-* Fr#1'w3r/ f3r F72 #2& Pr3)6 Peter Robinett [email protected] for DUSE VI, 2010-06-30 W,3 #1 I? ● Background in web programming with interpreted languages (PHP, Python, Javascript, etc) ● Likes long walks on the beaches ● Lift + Scala programmer for one year ● Loves both cats AND dogs ● Lift committer for approx. 6 months BUT only has minor commit to lift-flot to my name ● Likes fine wine and smooth jazz ● BUT active on mailing list and wiki ● Isn't very good at making funny bullet points W,#6 . L-*? Lift is an expressive and elegant framework for writing web applications. Lift stresses the importance of security, maintainability, scalability and performance, while allowing for high levels of developer productivity. Lift is inspired by Seaside, Rails, Django, Wicket, and beyond. W,9 F72? class AskName extends CometActor { def render = ajaxForm(<div>What is your username?</div> ++ text("",name => answer(name.trim)) ++ <input type="submit" value="Enter"/>) } class Chat extends CometActor with CometListener { private var userName = "" private var chats: List[ChatLine] = Nil private lazy val infoId = uniqueId + "_info" C31'6 private lazy val infoIn = uniqueId + "_in" private lazy val inputArea = findKids(defaultXml, "chat", "input") private lazy val bodyArea = findKids(defaultXml, "chat", "body") private lazy val singleLine = deepFindKids(bodyArea, "chat", "list") // handle an update to the chat lists // by diffing the lists and then sending a partial update // to the browser override def lowPriority = { case ChatServerUpdate(value) => val update = (value -- chats).reverse.map(b => AppendHtml(infoId, line(b))) partialUpdate(update) chats = value } // render the input area by binding the // appropriate dynamically generated code to the // view supplied by the template override lazy val fixedRender: Box[NodeSeq] = ajaxForm(After(100, SetValueAndFocus(infoIn, "")), bind("chat", inputArea, "input" -> text("", sendMessage _, "id" -> infoIn))) // send a message to the chat server private def sendMessage(msg: String) = ChatServer ! ChatServerMsg(userName, msg.trim) // display a line private def line(c: ChatLine) = bind("list", singleLine, "when" -> hourFormat(c.when), "who" -> c.user, "msg" -> c.msg) // display a list of chats private def displayList(in: NodeSeq): NodeSeq = chats.reverse.flatMap(line) // render the whole list of chats override def render = bind("chat", bodyArea, "name" -> userName, AttrBindParam("id", Text(infoId), "id"), "list" -> displayList _) // setup the component override def localSetup { askForName super.localSetup } // register as a listener def registerWith = ChatServer // ask for the user's name private def askForName { if (userName.length == 0) { ask(new AskName, "what's your username") { case s: String if (s.trim.length > 2) => userName = s.trim reRender(true) case _ => askForName reRender(false) } } } } "' C31172-69 W,9 Pr3)6#b0'? W,9 S%#0#? !00 6,' 23r1#0 r'$325, p075... !%63r5 Allows great AJAX, Comet support. <lift:comet type=”Clock”> The time is <clock:time />. </lift:comet> class Clock extends CometActor { override def defaultPrefix = Full("clock") // schedule a ping every 10 seconds so we redraw ActorPing.schedule(this, Tick, 10 seconds) private lazy val spanId = uniqueId+"_timespan" def render = { bind("time" -> timeSpan) } def timeSpan = (<span id={spanId}>{timeNow}</span>) override def lowPriority = { case Tick => partialUpdate(SetHtml(spanId, Text(timeNow.toString))) ActorPing.schedule(this, Tick, 10 seconds) } } case object Tick BUT, there were issues with th e EFPL library so David wrote LiftActor. This is actually a proof of Scala's strength. XHTML Pr3%(5-2+ Template: <lift:DuSE.sayHello> Hi <DuSE:name />. It's now <DuSE:datetime />. </lift:DuSE.sayHello> Snippet: import java.util.Date import scala.xml.{NodeSeq, Text} import net.liftweb.util.Helpers.bind object DuSE { def sayHello(xhtml: NodeSeq): NodeSeq = { User.currentUser.map(user => { bind(“DuSE”, xhtml, “name” -> Text(user.shortName), “datetime” -> Text((new Date).toString) ) }) openOr <div>You didn't log in!</div> } } R376-2+ Routing is done via SiteMap... val entries = Menu(Loc(“App Page”, “app” :: “view” :: Nil, “App Page”) :: Nil LiftRules.setSiteMap(SiteMap(entries :_*)) ... and redirects with partial functions! LiftRules.statefulRewrite.prepend({ case RewriteRequest(ParsePath("app" :: appID :: "index" :: Nil, _, _,_), GetRequest, _) => RewriteResponse("app":: "view" :: Nil, Map("appID" -> appID) }) Regex Free! W,#6 . L-* +33& #6? ● Comet, also AJAX ● X(HT)ML processing ● JSON ● REST ● As much or as little as you want done for you ● Secure ● Fast execution, fast development (IF you already know Lift) ● Great code:functionality ratio W,#6 . L-* b#& #6? ● High learning curve ● Stateless request/response cycle (but is possible) ● View-first, not MVC ● I.E. Does some things differently ● Statefulness can lead to lots of stuff in memory if you're not careful H3w 63 +'6 L-*'&? By Markus Lütkemeyer http://flickr.com/photos/helico/2245863081/ ! D-+r(5-32 32 V'r5-325 By Alan Sung http://flickr.com/photos/clsung/310886130/ ● 2.0-SNAPSHOT is quite stable ● RCs are really stable, only important bug fixes are added. We're at 2.0-RC2. ● Milestones are very stable. Last one was 2.0-M6. ● If you have crazy rules requiring that you MUST use 'official' releases, wait a week for 2.0. ● Moral of the story: DON'T use 1.x. ● PS Scala 2.8 support in 280_port_refresh, should see 3.0-SNAPSHOT after the 2.0 release. J3-2 6,' G33+0' Gr37p http://groups.google.com/group/liftweb R'#& 6,' G'66-2+ S6#r6'& G7-&' http://www.liftweb.net/docs/getting_started.html S/-1 6,' W-/- http://www.assembla.com/wiki/show/liftweb/ C,'%/376 6,' S%#0#&3%5 http://scala-tools.org/mvnsites-snapshots/liftweb/ C032' 6,' %3&' http://github.com/lift/lift * * Yep, since last night we've been using the new GitHub organizations feature. We're cutting edge like that. U5' #2 !r%,'6:' ● lift-archetype-basic ● lift-archetype-blank ● lift-archetype-jpa-basic ● lift-archetyp-jpa-blank-single ● lift-archetyp-jpa-blank ● lift-archetyp-sbt 5b6 simple-build-tool is THE way to do Scala projects. See http://www.assembla.com/wiki/show/liftweb/Using_SBT OR git clone git://github.com/dpp/lift_sbt_prototype.git Then cd into lift_sbt_prototype and type: sbt At the sbt prompt, type: update Then: jetty-run Point your browser to http://localhost:8080/ Mads Hartmann is working on sbt processors for Google Summer of Code. It should be awesome. M#v'2 http://www.assembla.com/wiki/show/liftweb/Using_Maven mvn archetype:generate \ -DarchetypeGroupId=net.liftweb \ -DarchetypeArtifactId=lift-archetype-blank \ -DarchetypeVersion=2.0-SNAPSHOT \ -DarchetypeRepository=http://scala-tools.org/repo-snapshots \ -DremoteRepositories=http://scala-tools.org/repo-snapshots \ -DgroupId=your.groupId \ -DartifactId=your.artifactId mvn jetty:run mvn scala:cc (jRebel license: http://www.zeroturnaround.com/scala-license/) D'14 #2& E8#1p0( http://demo.liftweb.net/ http://github.com/lift/lift/tree/master/examples/ http://github.com/dpp/lift-samples http://www.liftweb.net Q7(6-325? By Gillian Maniscalco http://flickr.com/photos/gillian_m/448800043/.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    32 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us