• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content

Loading…

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

Like this presentation? Why not share!

Elevate your webapps with Scala and Lift

on

  • 4,745 views

Presented at J-Fall 2010 conference in The Netherlands.

Presented at J-Fall 2010 conference in The Netherlands.

Statistics

Views

Total Views
4,745
Views on SlideShare
4,744
Embed Views
1

Actions

Likes
5
Downloads
0
Comments
0

1 Embed 1

http://www.linkedin.com 1

Accessibility

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />

Elevate your webapps with Scala and Lift Elevate your webapps with Scala and Lift Presentation Transcript

  • Elevate your webapps with Scala and Lift Sander Mak
  • Scala and Lift? • Introduc)on • View
layer • Interac)ve
apps:
Ajax
&
Comet • Model
layer • Wrapping
up
  • Who uses it? : :
  • Scala’s elevator pitch • SCAlable
LAnguage • True
OO
and
func)onal
programming • Concurrency:
actors,
immutability • Unifier
language: OO Dynamic, Static typing, agile performant FP
  • Lift’s elevator pitch • View‐first,
designer
friendly • Secure
by
default • Scalable,
servlet
based • Highly
interac)ve
apps
  • View first Step
1:
design
website
(or
download...) Step
2:
define
templa)ng
points
 Step
3:
bind
to
logic
from
view
 Pro’s:





designers
know
XHTML
(not
JSF,
JSP,
ERb) 


























no
logic
in
view,
ever! 






































pages
remain
valid
XHTML Con:







view
‘logic’
may
creep
into
code
  • View first - Templating default.html
with: <lift:bind name=”content” /> signup.html
with: <lift:surround with=”default” name=”content”> ... signup form ... also,
embed
fragments: <lift:surround /> <lift:embed what=”fragment1” />
  • View first - Snippets • Glue
code
view
 
model Not
MVC,
but: • Snippets
introduce – Dynamic data View – Dynamic behavior ViewModel • Many‐to‐many
rela)on
 between
pages/snippets Model • Stateless
or
stateful
  • Snippets - First steps XHTML <lift:surround with=”default”> <div id=”welcome”> <lift:helloWorld.sayHi /> </div> </lift:surround> Scala class HelloWorld { val msg = “Hi!” def sayHi(xhtml: NodeSeq): NodeSeq = <p>{msg}</p> }
  • Snippets - First steps XHTML <lift:surround with=”default”> XML literals, <div id=”welcome”> with escaping: <lift:helloWorld.sayHi /> }</tag> <tag>{ scalaExpr </div> Compiler checked well- formedness! </lift:surround> Scala class HelloWorld { val msg = “Hi!” def sayHi(xhtml: NodeSeq): NodeSeq = <p>{msg}</p> }
  • Snippets - Binding XHTML <lift:helloWorld.sayHi> <p><say:message /></p> <br /> <say:name /> </lift:helloWorld.sayHi> Scala class HelloWorld { def sayHi(xhtml: NodeSeq): NodeSeq = { val name = “Sander” bind(“say”, xhtml, “message” -> Text(“Hi!”), “name” -> Text(name)) } }
  • Snippets - Binding XHTML ‘Operators’ and implicit <lift:helloWorld.sayHi> conversions: “message”.->(Text(“hi”)) <p><say:message /></p> results in a tuple: <br /> (“message”, Text(“hi”)) <say:name /> </lift:helloWorld.sayHi> Scala class HelloWorld { def sayHi(xhtml: NodeSeq): NodeSeq = { val name = “Sander” bind(“say”, xhtml, “message” -> Text(“Hi!”), “name” -> Text(name)) } }
  • Snippets - Two way binding XHTML <lift:helloWorld.sayHi form=”POST”> <p><say:message /></p> <br /> <say:name><input type=”text” /></say:name> <input type=”submit” /> </lift:helloWorld.sayHi> Scala def sayHi(xhtml: NodeSeq): NodeSeq = { var name = “” bind(“say”, xhtml, “message” -> Text(“Hi!”), “name” -> SHtml.text(name, name = _)) }
  • Snippets - Two way binding XHTML <lift:helloWorld.sayHi form=”POST”> <p><say:message /></p> Anonymous closure! <br /> name = _ equal to <say:name><input type=”text” /></say:name> (x: String) => name = x <input type=”submit” /> </lift:helloWorld.sayHi> Scala def sayHi(xhtml: NodeSeq): NodeSeq = { var name = “” bind(“say”, xhtml, “message” -> Text(“Hi!”), “name” -> SHtml.text(name, name = _)) }
  • Snippets - Two way binding Scala class HelloWorld extends StatefulSnippet { var dispatch: DispatchIt = { case “sayHi” => sayHi } var name = “” def sayHi(xhtml: NodeSeq): NodeSeq = { def processForm() { if(name.length > 10) { S.error(“Get a nickname!”) } else { S.notice(name); unregisterThisSnippet() } } bind(“say”, xhtml, “message” -> Text(“Hi!”), “name” -> SHtml.text(name, name = _), “button” -> SHtml.submit(“Click”, processForm)) } }
  • Productive screens • Kicking up the abstraction level? • LiftScreen snippet – Trait for complex forms – Strongly typed form elements – Validation hooks, state management • Wizard snippet – Trait for multipage wizards – Back button handling & other goodies
  • Productive screens Scala object MyScreen extends LiftScreen { var color = field("Favourite color?", "", valMinLen(2, "Longer!"), valMaxLen(12, "Shorter!") ) var really = field("Really?", false) // Optional cross-field validation omitted def finish() { if(really.is) S.notice("I like "+ color.is + " too!") else S.warning("Please tell the truth...") } }
  • SiteMap • Structured entrypoint • Rewrite URLs (and params) • Access control • Nested menus, breadcrumbs • Associated snippet: <lift:Menu.builder /> • Usage optional
  • Rendering lifecycle URL Rewriting Custom dispatch (e.g. REST) Comet/Ajax processing SiteMap Locate template =
stateless Process =
statefull template
  • Ajax support Scala class HelloWorldAjax extends StatefulSnippet { var dispatch: DispatchIt = { case “sayHi” => sayHi } var name = “” def sayHi(xhtml: NodeSeq): NodeSeq = { def processForm() { if(name.length > 10) { S.error(“Get a nickname!”) } else { S.notice(name); unregisterThisSnippet() } } Shtml.ajaxForm( bind(“t”, xhtml, “message” -> Text(“Hi!”), “name” -> SHtml.text(name, name = _), “button” -> SHtml.ajaxSubmit(“Click”, () => processForm; Noop))) } }
  • Ajax support Scala class HelloWorldAjax extends StatefulSnippet { var dispatch: DispatchIt = { case “sayHi” => sayHi } var name = “” def sayHi(xhtml: NodeSeq): NodeSeq = { def processForm() { if(name.length > 10) { S.error(“Get a nickname!”) } else { S.notice(name); unregisterThisSnippet() } } Shtml.ajaxForm( bind(“t”, xhtml, “message” -> Text(“Hi!”), “name” -> SHtml.text(name, name = _), “button” -> SHtml.ajaxSubmit(“Click”, () => processForm; Noop))) } }
  • Ajax support Scala class HelloWorldAjax extends StatefulSnippet { JavaScript DSL expression, var dispatch: DispatchIt = {after server is sayHi } executed in client case “sayHi” => var name = “” finished. Examples: SetHtml(“elemId”, someNodeSeq) def sayHi(xhtml: NodeSeq): NodeSeq = { or def processForm() { JsCall(“myFunc”, Str(scalaString)) if(name.length > 10) { S.error(“Get a nickname!”) } else { S.notice(name); unregisterThisSnippet() } } Shtml.ajaxForm( bind(“t”, xhtml, “message” -> Text(“Hi!”), “name” -> SHtml.text(name, name = _), “button” -> SHtml.ajaxSubmit(“Click”, () => processForm; Noop))) } }
  • Ajax support • Robust: – Browser independent – Clientside retry mechanism • Lift handles plumbing – Adds necessary JS libraries to view – Centralized callback handler • Can ‘Ajaxify’ any element, not just links and form elements • JQuery or YUI based (pluggable)
  • Ajax support - widgets Scala class Data { val data = List("Green", "Yellow", "Blue", "Brown") def queryData(current: String, limit: Int) = data.filter(_.startsWith(current)) def autocomplete(xhtml: NodeSeq) = { bind("t", xhtml, "autofield" -> AutoComplete("", queryData, v => S.notice("Submitted " + v))) } }
  • Comet support Reverse
Ajax
/
server
push
  • Comet support Live
example
  • Lift persistence - Mapper • OR Mapper, relatively basic • But integrates very well – Schema and form generation – Type-safe queries Scala class Expense extends LongKeyedMapper[Expense] with IdPK { def getSingleton = Expense object dateOf extends MappedDateTime(this) object description extends MappedString(this,100) object account extends MappedLongForeignKey(this, Account) } object Expense extends Expense with LongKeyedMetaMapper[Expense] { override def dbTableName = "expenses" def entries(acc: Account) = Expense.findAll(By(Expense.account, acc.id)) }
  • Wrapping up Designer friendly, logic free views Concise; leverages Scala Comet/Ajax integration second to none Mature framework with great community Relatively steep learning curve Documentation slowly improving Stateful, but no session replication
  • Get started! For
the
Dutch: For
the
others: (free
ebook!)
  • Questions?