Uploaded on

Lift - Das Web-Framework für Scala

Lift - Das Web-Framework für Scala

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
2,589
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
54
Comments
0
Likes
3

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Das Web-Framework für Scala Heiko Seeberger Copyright WeigleWilczek 2009
  • 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. WARUM NOCH EIN WEB-FRAMEWORK? Lift pickt Rosinen von anderen Frameworks Lift bringt eigene innovative Ansätze 3
  • 4. DEMO: CHAT MIT 20 ZEILEN SCALA CODE 4
  • 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. DIE ANFÄNGE David Pollak Einfach zu benutzen Scala with Sails Sicher 2006 Keep the meaning with the bytes Einfach zu deployen 6
  • 7. HEUTE Lift 1.1 vor der Tür Sehr rege Community Etliche Sites powered by Lift 32 Committer 7
  • 8. FEATURES IM ANGEBOT Templates Sitemap Comet Persistenz AJAX User Management 8
  • 9. “MUSTERLÖSUNG” 9
  • 10. WEITERE FEATURES (UNVOLLSTÄNDIG) Wizards JPA und JTA OpenID JSON AMPQ OSGi Textile PayPay 10
  • 11. TEMPLATES 11
  • 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. TEMPLATES VERSCHACHTELN <lift:bind ... /> <lift:surround ...> 13
  • 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. 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. LIVE DEMO 16
  • 17. SITEMAP 17
  • 18. MENÜS UND ZUGRIFFSKONTROLLE 18
  • 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. 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. LIVE DEMO 21
  • 22. PERSISTENZ 22
  • 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. CRUD SUPPORT ... with CRUDify[Long, Game] 24
  • 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. LIVE DEMO 26
  • 27. USER MANAGEMENT 27
  • 28. CLAUSTHALER-PRINZIP 28
  • 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. LIVE DEMO 30
  • 31. AJAX SUPPORT 31
  • 32. BEISPIEL: LISTEN-ELEMENTE LÖSCHEN 32
  • 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. LIVE DEMO 34
  • 35. COMET SUPPORT 35
  • 36. CHATTEN LEICHT GEMACHT 36
  • 37. FRAGEN / DISKUSSION 37
  • 38. DANKE Kontakt: seeberger@weiglewilczek.com Mehr lernen: www.scalatraining.net 38