lift presentation at duse vi

Download Lift Presentation at DuSE VI

If you can't read please download the document

Upload: peter-robinett

Post on 16-Apr-2017

2.315 views

Category:

Technology


0 download

TRANSCRIPT

The Lift Framework for
Fun and Profit

Peter [email protected] VI, 2010-06-30

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

What is Lift?

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.

Why Fun?

Comet

class AskName extends CometActor { def render = ajaxForm(What is your username? ++ text("",name => answer(name.trim)) ++ )}

class Chat extends CometActor with CometListener { private var userName = "" private var chats: List[ChatLine] = Nil private lazy val infoId = uniqueId + "_info" 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) } } }}

The Community

Why Profitable?

Why Scala?

All the normal reasons, plus...

The time is .

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 = ({timeNow})

override def lowPriority = { case Tick => partialUpdate(SetHtml(spanId, Text(timeNow.toString))) ActorPing.schedule(this, Tick, 10 seconds) }}

case object Tick

Actors

Allows great AJAX, Comet support.

BUT, there were issues with the EFPL library so David wrote LiftActor. This is actually a proof of Scala's strength.

XHTML Processing

Template:

Hi . It's now .

Snippet:

import java.util.Dateimport 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 You didn't log in! }}

Routing

Routing is done via SiteMap...

LiftRules.statefulRewrite.prepend({ case RewriteRequest(ParsePath("app" :: appID :: "index" :: Nil, _, _,_), GetRequest, _) => RewriteResponse("app":: "view" :: Nil, Map("appID" -> appID)})

... and redirects with partial functions!

val entries = Menu(Loc(App Page, app :: view :: Nil, App Page) :: NilLiftRules.setSiteMap(SiteMap(entries :_*))

Regex Free!

What is Lift good at?

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

What is Lift bad at?

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

By Markus Ltkemeyerhttp://flickr.com/photos/helico/2245863081/

How to get Lifted?

High-as-a-kite bg image?

A Digression on Versions

By Alan Sunghttp://flickr.com/photos/clsung/310886130/

Conclusion?

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.

Join the Google Group

http://groups.google.com/group/liftweb

Read the Getting Started Guide

http://www.liftweb.net/docs/getting_started.html

Skim the Wiki

http://www.assembla.com/wiki/show/liftweb/

Checkout the Scaladocs

http://scala-tools.org/mvnsites-snapshots/liftweb/

Clone the code

http://github.com/lift/lift *

* Yep, since last night we've been using the new GitHub organizations feature. We're cutting edge like that.

Use an Archetype

lift-archetype-basic

lift-archetype-blank

lift-archetype-jpa-basic

lift-archetyp-jpa-blank-single

lift-archetyp-jpa-blank

lift-archetyp-sbt

sbt

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/

$ git clone ...$ sbt ...

Mads Hartmann is working on sbt processors for Google Summer of Code. It should be awesome.

Maven

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

Demos and Examples

http://demo.liftweb.net/

http://github.com/lift/lift/tree/master/examples/

http://github.com/dpp/lift-samples

http://www.liftweb.net

Questions?

By Gillian Maniscalcohttp://flickr.com/photos/gillian_m/448800043/