Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
lsug-lift.pdf
Search
Richard Dallaway
March 08, 2010
Programming
36
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
lsug-lift.pdf
London Scala User Group introduction to Lift web development, 8 March 2010.
Richard Dallaway
March 08, 2010
More Decks by Richard Dallaway
See All by Richard Dallaway
AI Roadmap
d6y
0
83
Voice to guide "difficult" recycling queries
d6y
0
96
Brighton Java: Day in the life...
d6y
0
270
Day in the Life of a Functional Programmer
d6y
0
670
Exoplanet Safari
d6y
1
520
Types Working For You
d6y
1
2.8k
Towards Browser and Server Utopia with Scala.js: an example using CRDTs
d6y
0
7.8k
Code Review Gems
d6y
1
2.1k
Woot for Lift
d6y
2
3.4k
Other Decks in Programming
See All in Programming
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
210
Workers Cache を知る
syumai
0
360
機械に任せるテスト、人が見るテスト ⽣成AIで引き直した、運⽤保守フェーズの線引き
dske104
0
190
ジョジョの世界をXRで再現する
mofurune
0
160
Vue Fes Japan の “作る側”に関わってみて
naokihaba
0
150
Compiling a real-world CLI tool to native with Static Hermes
tmikov2023
0
110
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
24
28k
現場と育てるRailsモデリング 〜Spreadsheetから始めたモデル設計〜
siroemk
2
530
速習iPhone Duo対応
yuukiw00w
2
980
當我們開始不讀 Code - AI Agent 時代,Code Review 與 Clean Code 還剩下什麼?
jame2408
1
130
APNsからLive Activityを開始する話
yumnumm
0
170
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
740
Featured
See All Featured
We Have a Design System, Now What?
morganepeng
55
8.4k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
450
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
520
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
[SF Ruby Conf 2025] Rails X
palkan
3
1.5k
How to make the Groovebox
asonas
2
2.5k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
360
Building AI with AI
inesmontani
PRO
1
1.3k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
460
The browser strikes back
jonoalderson
0
1.8k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
20k
Transcript
Getting started with Lift Richard Dallaway, @d6y
[email protected]
lsug.org
None
Struts Grails Rails PHP JSF Wicket GWT JAX-RS Stripes Spring
MVC Play Seam Seaside Lift Cocoon WebObjects
Struts Grails Rails PHP JSF Wicket GWT JAX-RS Stripes Spring
MVC Play Seam Seaside Lift Cocoon WebObjects Zero Plenty Weirdness
‛ ‛ ‛ ‛ http://liftweb.net
Versions 1.0.3 Updated Jan 2010 2.0 M2 Released Feb 2010
both for Scala 2.7.7
None
None
lift-base/lift-actor lift-base/lift-common lift-base/lift-json lift-base/lift-util lift-base/lift-webkit lift-modules/lift-amqp lift-modules/lift-facebook lift-modules/lift-imaging lift-modules/lift-jta lift-modules/lift-ldap
lift-modules/lift-machine lift-modules/lift-oauth lift-modules/lift-openid lift-modules/lift-osgi lift-modules/lift-paypal lift-modules/lift-testkit lift-modules/lift-textile lift-modules/lift-widgets lift-modules/lift-wizard lift-modules/lift-xmpp lift-persistence/lift-couchdb lift-persistence/lift-jpa lift-persistence/lift-mapper lift-persistence/lift-record $ find . -name lift\* -depth 2 -type d
Agenda • Part I: View first • Part II: Doing
stuff quickly • Part III: Ajax • Part IV: Real time web
The time on this server is: Mon Mar 08 18:40:51
GMT 2010.
<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>
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> }
<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>
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) ) } }
None
<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>
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 ) ) ) } }
None
$ 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):
$ 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
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] { }
<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>
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 _) ) } }
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 _) ) } }
None
$MJFOU 4FSWFS 5JNF #SPXTFS6* $0.&5$MJFOU User Activity Client Processing Display
Display Display Comet Event Bus Initialization Data Push Data Push Data Push Display Display Data Push Data Push Server-Side Processing Event Event Event Event Event
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 _) )
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))) } }
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
apress discount code LONDONSCALAUQUCUAVGLT
Next Meeting Traits & Mixins Kevin Monday 12 April Here,
Skillsmatter
None