W-JAX 09 - Lift

3,100 views
3,000 views

Published on

Lift - Das Web-Framework für Scala

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,100
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
59
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

W-JAX 09 - Lift

  1. 1. Das Web-Framework für Scala Heiko Seeberger Copyright WeigleWilczek 2009
  2. 2. WARUM SIND WIR EIGENTLICH HIER? “Lift is the only new framework in the last four years to offer fresh and innovative approaches to web development. It's not just some incremental improvements over the status quo, it redefines the state of the art. If you are a web developer, you should learn Lift ...” Michael Galpin, Developer, eBay 2
  3. 3. WARUM NOCH EIN WEB-FRAMEWORK? Lift pickt Rosinen von anderen Frameworks Lift bringt eigene innovative Ansätze 3
  4. 4. DEMO: CHAT MIT 20 ZEILEN SCALA CODE 4
  5. 5. FÜR’S PROTOKOLL • Projekt generieren mit mvn archetype:generate ... • ChatServer.scala anlegen • Chat.scala anlegen • chat.xhtml Template anlegen • In Boot.scala neues Menu zur SiteMap hinzufügen 5
  6. 6. DIE ANFÄNGE David Pollak Einfach zu benutzen Scala with Sails Sicher 2006 Keep the meaning with the bytes Einfach zu deployen 6
  7. 7. HEUTE Lift 1.1 vor der Tür Sehr rege Community Etliche Sites powered by Lift 32 Committer 7
  8. 8. FEATURES IM ANGEBOT Templates Sitemap Comet Persistenz AJAX User Management 8
  9. 9. “MUSTERLÖSUNG” 9
  10. 10. WEITERE FEATURES (UNVOLLSTÄNDIG) Wizards JPA und JTA OpenID JSON AMPQ OSGi Textile PayPay 10
  11. 11. TEMPLATES 11
  12. 12. WIE SCHREIBEN WIR TEMPLATES? <html> <head> In XHTML <title>kix</title> ... <body> <div class="container"> ... <div class="span-18 last"> <lift:Msgs showAll="true"/> mit Lift-Tags <lift:bind name="content"/> ... </div> <div class="span-12" style="text-align: center;"> <img src="/images/pbww.png"/> </div> ... 12
  13. 13. TEMPLATES VERSCHACHTELN <lift:bind ... /> <lift:surround ...> 13
  14. 14. SNIPPETS EINBINDEN class Games { Snippet def upcoming5(xhtml: NodeSeq) = bind("games", xhtml, "list" -> bindGames(Game upcoming 5, xhtml)) <lift:surround with="default" at="content"> ... <lift:Games.upcoming5> Snippet-Tag <games:list> <tr game:class=""> <td><span game:id=""><game:action/></span></td> <td><game:date/></td> <td><game:group/></td> Platzhalter im <td><game:location/></td> <td><game:teams/></td> Namespace game ... 14
  15. 15. SNIPPETS UND BINDING class Games { def upcoming5(xhtml: NodeSeq) = bind("games", xhtml, "list" -> bindGames(Game upcoming 5, xhtml)) private def bindGames(games: List[Game], xhtml: NodeSeq) = { val oddOrEven = OddOrEven() games flatMap { game => bind("game", chooseTemplate("games", "list", xhtml), "date" -> format(game.date.is, locale), "group" -> game.group.is.toString, "location" -> game.location.is, ... Platzhalter ersetzen 15
  16. 16. LIVE DEMO 16
  17. 17. SITEMAP 17
  18. 18. MENÜS UND ZUGRIFFSKONTROLLE 18
  19. 19. SITEMAP ANLEGEN val ifAdmin = If(() => User.superUser_?, () => RedirectResponse("/index")) val homeMenu = Menu(Loc("home", ("index" :: Nil) -> false, "Home")) ... val adminMenu = Menu(Loc("admin", ("admin" :: Nil) -> true, "Admin", ifAdmin), adminSubMenu: _*) val menus = homeMenu :: ... adminMenu :: User.sitemap LiftRules setSiteMap SiteMap(menus : _*) 19
  20. 20. MENÜS ANZEIGEN <html> <head> <title>kix</title> ... <body> <div class="container"> ... <div class="span-5"> <div class="menu"> <lift:Menu.builder/> </div> ... 20
  21. 21. LIVE DEMO 21
  22. 22. PERSISTENZ 22
  23. 23. MAPPER class Game extends LongKeyedMapper[Game] with IdPK { object group extends MappedEnum(this, Group) { override def displayName = ?("Group") } object team1 extends MappedTeam(this, "Team 1") object team2 extends MappedTeam(this, "Team 2") object date extends MappedDateTime(this) { override def displayName = ?("Date") } object location extends MappedString(this, 100) { override def displayName = ?("Location") } ... Keep the meaning with the bytes 23
  24. 24. CRUD SUPPORT ... with CRUDify[Long, Game] 24
  25. 25. SCHEMA ANLEGEN val dbVendor = new StandardDBVendor(Props get "db.driver" openOr "org.h2.Driver", Props get "db.url" openOr "jdbc:h2:kix", Empty, Empty) { override def maxPoolSize = Props getInt "db.pool.size" openOr 3 } DB.defineConnectionManager(DefaultConnectionIdentifier, dbVendor) Schemifier.schemify(true, Log.infoF _, Team, Game, Result, Tip, User) 25
  26. 26. LIVE DEMO 26
  27. 27. USER MANAGEMENT 27
  28. 28. CLAUSTHALER-PRINZIP 28
  29. 29. MORE THAN JUST CRUD class User extends MegaProtoUser[User] { override def shortName = { val s = super.shortName val i = s indexOf "@" if (i == -1) s else s.substring(0, i) } override def firstNameDisplayName = ?("Name") object points extends MappedInt(this) } 29
  30. 30. LIVE DEMO 30
  31. 31. AJAX SUPPORT 31
  32. 32. BEISPIEL: LISTEN-ELEMENTE LÖSCHEN 32
  33. 33. SCALA API FÜR AJAX def editDelete(tip: Tip) = { def delete = { Tip delete_! tip SetHtml(tip.id.is.toString, NodeSeq.Empty) } renderEditDelete(tip, delete _) } private def renderEditDelete(tip: Tip, jsCmd: () => JsCmd) = link("/tips/edit", () => currentTip(Full(tip)), editImg) ++ Text("") ++ ajaxDeleteImg(ajaxInvoke(jsCmd)) 33
  34. 34. LIVE DEMO 34
  35. 35. COMET SUPPORT 35
  36. 36. CHATTEN LEICHT GEMACHT 36
  37. 37. FRAGEN / DISKUSSION 37
  38. 38. DANKE Kontakt: seeberger@weiglewilczek.com Mehr lernen: www.scalatraining.net 38

×