Keep on moving

あんまりまとまってないことを書きますよ

たぶん日本で一番速いPlay!2.0本感想

前から出る出るっていう話だけ出ていたPlay!framework2.0本が出ましたね。
Java/Scalaで別々の本になっています。

Manning: Play for Scala
Manning: Play for Java

作者は、Scala版はドキュメントの責任者をやってる Peter Hilton、Java版は1.2.X系のリーダーNicolas leroux

とりあえず両方買って現状のものを斜め読みしたので現状(4/27)の感想を書いときます。

感想





まとめ

まだ全体が書かれてないので何とも言えないのですが、一般的なWebシステムの作り方+テスト+Deployが
中心になりそうです。Tutorial++って感じですね。
上でも書いたけど、どちらかというと初心者〜中級者向けがターゲットみたいです。
これから始めたいって方は買ってもいいとおもいます。
あとJavaの方が若干技術よりな話題が多い気がする。

Play2.0の目玉機能である非同期なところとか、Comet/Websocket周りとかの話はなさそう。
個人的には速いところPart III: Advanced techniques が読みたいですね。
あと現状MEAPなので、これ読んでみたいとかはOpen Forumで言えるといいなー
http://www.manning-sandbox.com/forum.jspa?forumID=810

Play2.0で自作プラグインを書く

motivation

Play2.0ではプラグインの書き方の資料はありません。MLを見てる感じだとsbtのsubprojectとして
プラグインを書くのが一般的のようです。他のモジュールを参考にして、github上に

書き方

  1. sbtの構成で書く

現状のModuleはフォルダ構成がまちまちなのですが、今後を考えるとsbtの構成で書くようにした方が良さそう

.
├── build.sbt
├── project
│   ├── plugins.sbt
├── src
│   └── main
│       └── scala
│           └── com
│               └── github
│                   └── masahitojp
│                       └── play2
│                           └── sample
│                               └── SamplePlugin.scala
└── version.sbt
  1. SamplePluginの書き方

Scalaでの書き方を説明します。play.api.Pluginを継承します。
Play!1.Xではたくさんのフックイベントが存在するのですが、2.Xではいまのところ
onStart/onStop/enabledのみ使えます。

package com.github.masahitojp.play2.sample

import play.api._

class SamplePlugin(val app: Application) extends Plugin {
  val name = "sample"
  // 起動時に実行される
  override def onStart() {
    Logger.info("sample on start")
  }
  // アプリケーション終了時に実行
  override def onStop() {
    Logger.info("sample on end")
  }
  // アプリケーションの有効フラグ
  override def enabled() = !app.configuration.getString("SamplePlugin")
      .filter(_ == "disabled").isDefined
}
  1. 公開する

他のモジュールではSonatypeを使ってmaven projectを使うのが一般的みたい。
公開の仕方はこちらを参考にすると良いです。
なおpgp用のキーの作成が必要です。

また、sonatypeを使う場合はbuild.sbtに以下の行を加えておくと良い用です。

// Configuration required for deploying to sonatype

publishMavenStyle := true

publishTo <<= version { (v: String) =>
  val nexus = "https://oss.sonatype.org/"
  if (v.trim.endsWith("SNAPSHOT"))
    Some("snapshots" at nexus + "content/repositories/snapshots")
  else
    Some("releases" at nexus + "service/local/staging/deploy/maven2")
}

pomIncludeRepository := { _ => false }

publishArtifact in Test := false

pomExtra := (
  <url>http://github.com/masahitojp/play2-sample-module</url>
  <inceptionYear>2012</inceptionYear>
  <licenses>
    <license>
      <name>Apache 2</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
      <distribution>repo</distribution>
      <comments>A business-friendly OSS license</comments>
    </license>
  </licenses>
  <scm>
    <url>git@github.com:masahitojp/play2-sample-module.git</url>
    <connection>scm:git:git@github.com:masahitojp/play2-sample-module.git</connection>
  </scm>
  <developers>
    <developer>
      <name>Nakamura Masato</name>
      <email>randomstep@gmail.com</email>
      <url>http://masahito.me/</url>
      <roles>
        <role>Author</role>
      </roles>
      <organization>Nakamura Masato</organization>
    </developer>
  </developers>)

導入の仕方

  1. project/Build.scala
    val appDependencies = Seq(
      // Add your project dependencies here,
     "com.github.masahitojp" %% "play2-sample-module" % "1.0.0-SNAPSHOT"
    )

    val main = PlayProject(appName, appVersion, appDependencies, mainLang = SCALA).settings(
      // Add your own project settings here      
      resolvers += "Sonatype OSS Snapshots Repository" at "http://oss.sonatype.org/content/groups/public"
    )
  1. conf/play.pluginを書く

優先度:使いたいplginのクラス

優先度は小さいほど先に実行されるようです。

10000:com.github.masahitojp.play2.sample.SamplePlugin

summary

まだsbtについてはちゃんと理解できていませんが、pluginの書き方は理解できました。
本当は こちら の用にgithubから直接
取得する方法を調べたのですが、うまく行きませんでした。こちらは後で追加調査する予定です。
先人に感謝。

Play Framework 2.0 ソースコードリーディングの会 で発表してきました。

Play Framework 2.0 ソースコードリーディングの会 - [PARTAKE]で発表してきました。
これでPlay2.0での発表は3度目になりました。

ソースコードの読み方の話もしたんですが、また今度記事にします。

Play2.0でmoreStylesとmoreScriptsの書き方をいろいろ考えてたら、テンプレートの使い方がいろいろわかってきた

id:kiris60 さんの別解的な書き方があるので一応紹介。
でも書くなら kirisさん方式が個人的には一番好きだな。

http://kiris.hatenablog.com/entry/2012/01/26/172446

気づき点(仕様?)

  • Play2.0 or Play1+ScalaのテンプレートはScalaの関数として動作
  • {}の仕様

テンプレートからテンプレートに引数を渡すときに、
中括弧({})で囲むと暗黙的に"play.api.templates.Html"に変換されるっぽい。
"@"をつけてScalaの処理を加えて、明示的に変数化してもplay.api.templates.Htmlになります。

@main("ここは任意の型が使えるが、"){
  <!-- ここはplay.api.templates.Html型になる  -->
}
  • 1系と同様にテンプレートでもエラーがあれば警告してくれます

f:id:Ehren:20120201161330j:image

こんなかんじ(例1 )

@(title: String)(content: Html)(moreStyles: Html)(moreScripts: Html)

<!DOCTYPE html>

<html>
    <head>
        <title>@title</title>
        
        <link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")">

	    @moreStyles
        <script src="/assets/javascripts/jquery-1.7.1.min.js" type="text/javascript"></script>
	    @moreScripts
    </head>
  ...
@(message: String)

@import tags._

@main("Welcome to Play 2.0") {
    
    @play20.welcome(message)
    
}{
    @styleSheets(
      List(
        ("screen", "stylesheets/main.css")
      )
    )
}{

    @javaScripts(
      List(
        "javascripts/underscore.js",
        "javascripts/underscore.string.js"
      )
    )
}

こんな書き方も可能

カリー化っぽく書くこともできます。

@(title: String)(moreStyles: Seq[(String, String)]=Nil)(moreScripts: Seq[String]=Nil)(content: Html)

@import tags._

<!DOCTYPE html>

<html>
    <head>
        <title>@title</title>
        <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">
        <link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")">

        
        @styleSheets(moreStyles)
        <script src="@routes.Assets.at("javascripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
@javaScripts(moreScripts)

    </head>
    <body>
        @content
    </body>
</html>
@(message: String)

@import tags._

@main("Welcome to Play 2.0")()(
          List(
        "javascripts/underscore.js",
        "javascripts/underscore.string.js"
        )
    ){
    
    @play20.welcome(message)
    
}

まとめ

Play2系ではビルダがsbtになったお陰でテンプレートコンパイル時のビルド時間が早くなってくれて嬉しい。*1
Play+Scalaで開発するときのサクサク感が1系よりもあがった気がします。

*1:1+Scalaはテンプレートで一文字変更しただけでも結構ビルドに時間がかかる

Play20でEclipseプロジェクトを作る

これはPlay!framework 2.0 RC1-SNAPSHOTのお話です。betaでは動かないかも。

Play20ではsbteclipseがsbtのDependencyに登録されています。


https://github.com/playframework/Play20/blob/master/framework/project/Build.scala#L83

基本的にコマンド実行でOKです。コマンドはPlay!framework 1系と同じです。*1

$ play eclipsify

*1: netbeansify,idealizeは現状ありません。

Play20でIntelliJを使う

Play20で IntelliJをのプロジェクト化する方法をまとめておきます。
前にMLでIntelliJに取り込む方法が紹介されてたけどこちらの方が簡単なので紹介します。*1

やりかた

  • Play RC1-snapshotをビルド
  • "play new hoge"で新規プロジェクトを作成
  • "hoge/project/plugin.sbt" を以下のように変更
resolvers ++= Seq(
    DefaultMavenRepository,
    Resolver.url("Play", url("http://download.playframework.org/ivy-releases/"))(Resolver.ivyStylePatterns),
    "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"
)

addSbtPlugin("play" % "sbt-plugin" % "2.0-RC1-SNAPSHOT")

resolvers += "sbt-idea-repo" at "http://mpeltonen.github.com/maven/"

addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.0.0")
  • プロジェクト内で play コマンドを実行
  • sbt コンソールで "update"コマンド実行.
  • sbt-ideaがきちんと登録されたら、"gen-idea"コマンド実行
  • IntelliJを開いて、"File"メニューから,"Open Project"でPlay プロジェクトのフォルダを選択
  • できました.-)

f:id:Ehren:20120129233950p:image

まとめ

Play2.0はsbtベースになってくれたお陰でsbtの拡張がそのまま使えるのが便利ですね。
Play2.0 finalまでにコマンドが取り込まれる予定らしいのでそれまではsbtの拡張を探して使うのが良さそうですね。
なお、eclipse版もあるので、後日試してみたいところです。
先人に感謝。

typesafehub/sbteclipse · GitHub

*1: 実はPlay!flamework AdventCalendar 2週目以降用のネタだったのですが、現状に合わせて大幅に変更して今更公開します。