scala+liftで遊ぼう
Upcoming SlideShare
Loading in...5
×
 

scala+liftで遊ぼう

on

  • 3,432 views

初心者によるLift入門…のようなもの。

初心者によるLift入門…のようなもの。

Statistics

Views

Total Views
3,432
Views on SlideShare
3,432
Embed Views
0

Actions

Likes
4
Downloads
24
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

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

    scala+liftで遊ぼう scala+liftで遊ぼう Presentation Transcript

    • Scala + Lift で遊ぼう よーく(@youku_s) わんくま同盟 名古屋勉強会 #19
    • 自己紹介HN:よーく(@youku_s)新社会人プログラマ in 名古屋仕事で使っている(た)もの: VB.NET, Java興味があるもの: Scala, C++, Haskell, 離散数学 幸せになるための方法全般, TRPG, etc… わんくま同盟 名古屋勉強会 #19
    • 本日の内容• Liftについて – 概要 – 機能の紹介• Liftのプロジェクトを作ろう – セットアップ – Viewの記述方法 – Modelの記述方法 わんくま同盟 名古屋勉強会 #19
    • Scalaとは• 関数型+オブジェクト指向の静的型付け言語• Javaとの互換性がある• Javaに比べて高機能にかつ短く書ける• 便利な機能がたくさん – 型推論 – パターンマッチ – 高階関数+ラムダ式 – immutableなコレクションの操作 – Option/Either型(null とか絶対おかしいよ!) わんくま同盟 名古屋勉強会 #19
    • 詳しいことは・・・とりあえずこの本を読めばいいと思います わんくま同盟 名古屋勉強会 #19
    • Liftについて• フルスタックなWebフレームワーク• 特徴 – Viewを中心としたアーキテクチャ – Comet/AjaxをScalaコードだけで実現できる – ORMapper、NoSQLのサポート – 脆弱性への対応 – 設定はScalaのコード/DSLで記述 わんくま同盟 名古屋勉強会 #19
    • Viewに着目したアーキテクチャ簡略図 LiftFilter主に作成する部分 View テンプレート 画面中のコンポーネントの レンダリングBoot.scala Snippet データアクセス DB接続、etc Model わんくま同盟 名古屋勉強会 #19
    • View First アプローチ• View = テンプレート + Snippet• テンプレート – HTML(5)/XHTMLで記述 – ロジックはコンポーネントごとにSnippetへ分離 – Snippetとの関連付けに特殊な記号を用いない • HTMLとして単体で見た目を確認できる• Snippet – Scalaで記述 – テンプレートのタグに処理を流し込む わんくま同盟 名古屋勉強会 #19
    • Comet/Ajax• ScalaのコードだけでAjaxな処理を記述可能 – 処理内容として関数を渡す(Function Mapping) • JavaScriptのコードが生成される• Comet – サーバー側で発生したイベントをクライアントから のRequestなしに、クライアントに通知する機能 – Scalaの並列処理機能のActorを用いて実装され ている わんくま同盟 名古屋勉強会 #19
    • 用意するもの• Lift 2.4M4 – http://liftweb.net/ – /解凍済みフォルダ/scala_29/lift_basic • すでにいろいろ設定されているLiftプロジェクト • テンプレートにHTML5を使える• Scala 2.9.1-final – http://www.scala-lang.org/• simple build tool(sbt) 0.11.0 – https://github.com/harrah/xsbt/wiki わんくま同盟 名古屋勉強会 #19
    • sbtについて• Scalaで書かれたScalaの開発環境 – 依存関係の管理、ビルド、CIっぽいこととか• 大別して0.7.x系と0.10.x系(以降)がある – 互換性がほとんどない – 多くのプロジェクトで0.10.x系への移行が進んで いる…らしい – Lift2.4M4のデフォルトは0.7.x系• 0.10.x系使いましょう – 現在(2011/10/15)最新はsbt 0.11.0 わんくま同盟 名古屋勉強会 #19
    • sbtの設定 0.7.x → 0.11.0• プロジェクトの依存関係の設定 – build.sbt(長いので次へ)• sbt webプラグインの設定 – project/plugins.sbtlibraryDependencies <+= sbtVersion(v =>"com.github.siasia" %% "xsbt-web-plugin" % (v+"-0.2.4"))• sbtバージョンの指定 – project/build.propertiessbt.version=0.11.0 わんくま同盟 名古屋勉強会 #19
    • プロジェクトの依存関係の設定(build.sbt)name := “project_name"seq(webSettings: _*)resolvers ++= Seq( "Java.net Maven2 Repository" at "http://download.java.net/maven/2/", ライブラリの入手 "Scala Tools Snapshots" at "http://scala-tools.org/repo-snapshots", "Typesafe Snapshots" at "http://repo.typesafe.com/typesafe/snapshots" 元)libraryDependencies ++= { val liftVersion = "2.4-M4" // Put the current/latest lift version here Seq( "net.liftweb" %% "lift-webkit" % liftVersion % "compile->default", "net.liftweb" %% "lift-mapper" % liftVersion % "compile->default", Liftライブラリ "net.liftweb" %% "lift-wizard" % liftVersion % "compile->default")}libraryDependencies ++= Seq( "org.mortbay.jetty" % "jetty" % "6.1.22" % "container", "org.scala-tools.testing" % "specs_2.9.0" % "1.6.8" % "test", "junit" % "junit" % "4.8" % "test->default", その他のライブ "javax.servlet" % "servlet-api" % "2.5" % "provided->default", ラリ群 "com.h2database" % "h2" % "1.2.138", "ch.qos.logback" % "logback-classic" % "0.9.26" % "compile->default") わんくま同盟 名古屋勉強会 #19
    • Liftでよく使うClass / Objectについて• net.liftweb.http.S – HTTP Request/Response情報を扱う – セッション・Cookie管理, リダイレクト, etc• net.liftweb.http.SHtml – htmlのタグを生成する – Ajaxコンポーネントなども扱う• net.liftweb.http.LiftRules – Liftの設定を行う – コードのディレクトリ, jQueryの使用, etc わんくま同盟 名古屋勉強会 #19
    • Liftでよく使うClass / Objectについて• net.liftweb.common.Box – Full, Empty, Failureの三種類の値を持ちうる型 • 有効な値が取れればFull • Liftの例外処理で使われている• net.liftweb.http.RequestVar – Requestを受け取るためのObject – 継承して用いるobject name extends RequestVar("") わんくま同盟 名古屋勉強会 #19
    • Liftプロジェクトの構成• src/main/scala/code – Snippet、ModelのScalaコード• src/main/scala/bootstrap/lift web – Boot.scala• src/main/webapp – テンプレートなど• target – コンパイル時に生成わんくま同盟 名古屋勉強会 #19
    • Boot.scala• メニューの設定 – SiteMap()の要素にMenuを追加する – Menu(S ? ”表示名”) / ”テンプレートの相対パス”class Boot { def boot { /* DB設定略 */ Schemifier.schemify(true, Schemifier.infoF _, User) LiftRules.addToPackages("code") def sitemap = SiteMap( Menu.i("Home") / "index" >> User.AddUserMenusAfter, Menu(Loc("Static", Link(List("static"), true, "/static/index"), "Static Content"))) /* HTML5、jQuery、Ajaxなどの設定 略 */ }} わんくま同盟 名古屋勉強会 #19
    • Boot.scala• Schemefier – 指定したModelとDBのテーブルを自動同期class Boot { def boot { /* DB設定略 */ Schemifier.schemify(true, Schemifier.infoF _, User) LiftRules.addToPackages("code") def sitemap = SiteMap( Menu.i("Home") / "index" >> User.AddUserMenusAfter, Menu(Loc("Static", Link(List("static"), true, "/static/index"), "Static Content"))) /* HTML5、jQuery、Ajaxなどの設定 略 */ }} わんくま同盟 名古屋勉強会 #19
    • テンプレートについて• <body class="lift:content_id=main"> – id=“main”を持つ要素の内容をテンプレートとして 処理する – 省略すると、テンプレート全体が処理されるTemplate(抜粋)<body class="lift:content_id=main"> <div id="main" class="lift:surround?with=default;at=content"> <h2>Welcome to your project!</h2> <p> <span class="lift:helloWorld.howdy"> Welcome to your Lift app at <span id="time">Time goes here</span> </span> </p> </div></body> わんくま同盟 名古屋勉強会 #19
    • テンプレートについて• <div(中略)class="lift:surround?with=default;at=content"> – 囲まれた内容を処理し、レイアウトdefault.html の”content”の位置に流し込むTemplate(抜粋)<body class="lift:content_id=main"> <div id="main" class="lift:surround?with=default;at=content"> <h2>Welcome to your project!</h2> <p> <span class="lift:helloWorld.howdy"> Welcome to your Lift app at <span id="time">Time goes here</span> </span> </p> </div></body> わんくま同盟 名古屋勉強会 #19
    • テンプレートについて• <span class="lift:helloWorld.howdy"> – 囲まれた範囲にhelloWorld Snippetのhowdyメ ソッドのレンダリング処理を適用するTemplate(抜粋)<body class="lift:content_id=main"> <div id="main" class="lift:surround?with=default;at=content"> <h2>Welcome to your project!</h2> <p> <span class="lift:helloWorld.howdy"> Welcome to your Lift app at <span id="time">Time goes here</span> </span> </p> </div></body> わんくま同盟 名古屋勉強会 #19
    • レイアウトについて<html xmlns="http://www.w3.org/1999/xhtml" xmlns:lift="http://liftweb.net/"> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <meta name="description" content="" /> <meta name="keywords" content="" /> </head> <body> <div class="container"> <div class="column span-6 colborder sidebar"> <hr class="space" > <span class="lift:Menu.builder"></span> <div class="lift:Msgs?showAll=true"></div> <hr class="space" /> </div> <div class="column span-17 last"> <div id="content">The main content will get bound here</div> </div> </div> </body></html> わんくま同盟 名古屋勉強会 #19
    • レイアウトについて• webapp/template-hidden以下のhtml – <div id="content"></div> • テンプレートのlift:surround at=“content”で指定した内 容の埋め込み位置 • <lift:bind name=“content” />でも可 – <span class="lift:Menu.builder"></span> • Boot.scalaで設定したMenu Snippetを用いて、タグの 位置にメニューを生成する – <div class="lift:Msgs?showAll=true"></div> • タグの位置にメッセージの表示を行うSnippet わんくま同盟 名古屋勉強会 #19
    • Snippet• メソッドが一つのコンポーネントに対応する – <lift:helloWorld.howdy>タグ内 – class=”lift:helloWorld.howdy”が指定されたタグTemplate(抜粋)<span class="lift:helloWorld.howdy"> Welcome to your Lift app at <span id="time">Time goes here</span></span>Snippetclass HelloWorld { lazy val date: Box[Date] = DependencyFactory.inject[Date] def howdy = "#time *" #> date.map(_.toString)} わんくま同盟 名古屋勉強会 #19
    • Snippet• Snippetとテンプレートの関連付け – Helpers.bindを用いる方法 • 割愛(こっちは資料多いし…) – CSSセレクタを用いる方法 • #>演算子を使うSnippetdef howdy = "#time *" #> date.map(_.toString)Template(抜粋)Welcome to your Lift app at <span id="time">Time goes here</span>id=“time”を持つ要素の内容を左辺の文字列で置換 わんくま同盟 名古屋勉強会 #19
    • 左辺 CSSセレクタによる関連付け記法 意味#hoge id=“hoge”を持つ要素を選択する.(ピリオド)hoge classにhogeを含む全ての要素を選択するattr_name=value 属性attr_nameの値がvalueである全ての要素を選択する置換規則 例 意味(なし) “#hoge” 一致した全ての要素を右辺で置換* “#hoge *” 一致した全ての要素の内容を右辺で置換[attr] “#hoge [href]” 一致した全ての要素の属性attrの値を右辺で置換右辺• String, Box, NodeSeq, List[String], List[NodeSeq], etc• コレクションを要素の内容に適用した場合、要素が個数分コ ピーされる わんくま同盟 名古屋勉強会 #19
    • Model• classとコンパニオンobjectの使い分け – スキーマ定義:class • traitのミックスインによってModelに機能を追加できる – IdPK:主キーにIdを自動で振る機能を追加するtrait • 属性はobject(シングルトンなオブジェクト)で定義class TwitterId extends LongKeyedMapper[TwitterId] with IdPK { override def getSingleton = TwitterId object screenName extends MappedString(this, 100) object password extends MappedString(this, 100) object user extends MappedLongForeignKey(this, User)} わんくま同盟 名古屋勉強会 #19
    • Model• classとコンパニオンobjectの使い分け – コンパニオンobject? • 同じファイル内で定義されたclassと同じ名前のobject • 同名クラスのprivateなメンバにアクセスできる – Modelへの操作、設定:コンパニオンobject • LongKeyedMetaMapper traitのミックスインでCURD 操作のAPIを追加object TwitterId extends TwitterId with LongKeyedMetaMapper[TwitterId] わんくま同盟 名古屋勉強会 #19
    • 参考• Lift全般 – Scala実践プログラミング – Scala+Liftによる実践Webアプリケーション開発 • http://codezine.jp/article/corner/322 – Exploring Lift • http://exploring.liftweb.net/ – Lift Wiki • http://www.assembla.com/wiki/show/liftweb/ わんくま同盟 名古屋勉強会 #19
    • 参考• sbtの設定 – sbt – GitHub • https://github.com/harrah/xsbt/wiki – sbt徹底解説 • http://www.slideshare.net/KenjiYoshida/scalakaigi1 sbt – siasia / xsbt-web-plugin - GitHub • https://github.com/siasia/xsbt-web-plugin – lacy / lift-quickstart - GitHub • https://github.com/lacy/lift-quickstart わんくま同盟 名古屋勉強会 #19
    • ご清聴ありがとうございました! わんくま同盟 名古屋勉強会 #19