2012年5月9日水曜日

Play framework2.0のテンプレートエンジン部分意訳

Play framework2.0のThe template engineを意訳しました。

私は英語が苦手なタイプの人間なので間違っている部分は多々あると思います。
例のごとく、もし私の訳が間違っていても責任は負えませんのであしからず・・・
正確なものを読みたい方は原典をどうぞ。

http://www.playframework.org/documentation/2.0/ScalaTemplates

なお、日本Playframeworkユーザー会さんの方で翻訳作業が進行中のようですので、そちらを待たれるという手もあります。

それではどうぞ!

Play2.0のテンプレートエンジンはScalaがベースです

APS.NETのRazorにインスパイアされました。
コンパクトで簡単でどんなテキストエディタでも編集できます。
新しい言語を覚える必要はありません!

テンプレートはScalaだからコンパイルされます。
つまり、ブラウザで通常のプログラムと同じようにテンプレートのエラーを確認できます。

overview

Play2.0のテンプレートは、ちょっとしたScalaのコードを含んだシンプルなテキストファイルです。
HTMLやXML、CSVといった普通のテキストベースのフォーマットを生成できます。
テンプレートシステムは、デザイナが簡単に扱えるようにして、HTMLを快適に感じるようにしました。

テンプレートはコンパイルされて、普通のScalaの関数になります。
もし、「views/Application/index.scala.html」というテンプレートを作った場合、「views.html.Application.index」という関数が生成されます。

上記のディレクトリにファイルを作ったと仮定して、以下はシンプルなテンプレートの例です。

@(customer: Customer, orders: Seq[Order])
<h1>Welcome @customer.name!</h1>
<ul>
@orders.map { order =>
 
<li>@order.title</li>
}
</ul>

上記のテンプレートは、ただのテンプレートとしてだけではなく、どんなScalaコードからでも呼び出せます。
以下がサンプルです

val html = views.html.Application.index(customer, orders)

※注意(公式にない私的メモ)
Applicationというディレクトリがサンプルにあるけど、なんかこれはデフォルトコントローラのApplication.scalaと混同してしまって分かりにくかった。
viewsディレクトリの下に、「hoge/piyo.scala.html」というファイルを作った場合は、「views.html.hoge.piyo()」になります。
views.htmlは決め打ちで、後は通常のパッケージみたいに.区切りでディレクトリ階層を書いて行って、最後にテンプレートの先頭のファイル名(scala.htmlは不要)を書く感じ

@という魔法

Scalaテンプレートで、@を特殊な文字として扱います。
この@マークがある場所は、Scalaステートメントが始まる場所です。
@で始まるScalaステートメントをを態々閉じる必要はありません。
フレームワークがうまいことやってくれます。

Hello @customer.name!
       ^^^^^^^^^^^^^^^^^^^^^^^
        Scala code

テンプレートエンジンはあなたのコードを解析して、コードの終わりを自動的に検知してくれます。
ただし、もし複数のトークンを使うようなステートメントは明示的に括弧を使ってね。

Hello @(customer.firstName + customer.lastName)!
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                    Scala Code

さらに、普通のScalaコードのように中括弧を使ってステートメントを書くこともできます。

Hello @{val name = customer.firstName + customer.lastName; name}!
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                             Scala Code

そう!@は特殊な文字なのです。
時々@をエスケープしたいときもあるでしょう。
その時は@@を使ってください

My email is bob@@example.com


テンプレートパラメータ

テンプレートはシンプルな機能なので、引数が必要です。
テンプレートファイルの先頭行に宣言する必要があります。

@(customer: models.Customer, orders: Seq[models.Order])

さらにデフォルト引数も使えます。

@(title: String = "Home")

あと、いくつかのパラメータグループも使えます。

@(title:String)(body: => Html)

そしてimplictパラメータも使えます。

@(title: String)(body: => Html)(implicit request: play.api.mvc.Request)


イテレータ

Scalaのfor分は当然使えます。
ただし、以下の場合だとテンプレートコンパイラはコードブロックの上にyieldを置くことに注意してください。

<ul>
@for(p <- products) {
 
<li>@p.name ($@p.price)</li>

}
</ul>

恐らく分かるでしょうが、for分は典型的なmapのシンタックスシュガーになっています。


<ul>
@products.map { p =>
 
<li>@p.name ($@p.price)</li>

}
</ul>


ifブロック

ifブロックは特別なものではありません。
普通のScalaのifと同じように使い、以下のようになります。

@if(items.isEmpty) {
 
<h1>Nothing to display</h1>
} else {
 
<h1>@items.size items!</h1>
}


パターンマッチング

テンプレートの中でパターンマッチングを使うこともできます。

@connected match {
   
  case models.Admin(name) => {
    Connected as admin (@name)
  }

  case models.User(name) => {
    Connected as @name
  }
   
}


再利用可能なブロックの宣言

再利用可能なブロックを利用できます。

@display(product: models.Product) = {
  @product.name ($@product.price)
}

<ul>
@products.map { p =>
  @display(product = p)
}
</ul>

さらに、再利用可能なScalaによるコードブロックを宣言することもできます

@title(text: String) = @{
  text.split(' ').map(_.capitalize).mkString(" ")
}

<h1>@title("hello world")</h1>

Note:Scalaによるコードブロックをテンプレートの中で宣言するのは時々は有効な手段です。
しかし、複雑なロジックを記述するのに、テンプレートはベストな場所ではないということを覚えておいてください。
多くの場合、複雑なコードは純粋なScalaソースファイルに外出ししておいた方が良いです。
(views/パッケージの下にそういったソースファイルを格納することもできます。)

※注意(公式にない私的メモ)
つまり普通にテンプレートの中で関数を宣言できるということ。

PlayFramework2.0の決まりによって、再使用可能なコードはimplictという名前で定義されます。

@implicitFieldConstructor = @{ MyFieldConstructor() }


再利用可能な値の宣言

definingヘルパーを使って、スコープ内で再利用できる値を定義できます。

@defining(user.firstName + " " + user.lastName) { fullName =>
 
    Hello @fullName

}


ステートメントのインポート

テンプレートの先頭でインポートしたいものはどんなものでもインポートすることが来ます。
(もしくはサブテンプレート)

@(customer: models.Customer, orders: Seq[models.Order])

@import utils._

...


コメント

サーバサイドのみのコメントを@* *@を使って書くことが出来ます。

@*********************
 * This is a comment *
 *********************@  

テンプレートの最初の行にコメントを書くことで、Scala API docとして扱うことが出来ます

@*************************************
 * Home page.                        *
 *                                   *
 * @param msg The message to display *
 *************************************@
@(msg: String)

<h1>@msg</h1>


エスケープ

デフォルトでは、動的なコンテンツはテンプレートの種類に応じてエスケープされます。(HTMLとかXML)
もしエスケープさせずにそのまま出力したい場合には、出力したい生データをテンプレートのコンテントタイプでラップしてください。

  <p>@Html(article.content) <p> 


以上で、公式のテンプレートエンジン部分の意訳は終了!
PlayFramework1.2の頃に翻訳されたサイトを見ていましたが、チュートリアルが分かりやすいという点が本当に素晴らしいですね。
英語は苦手ですが、難しい表現もないようなので英語の勉強にももってこいなのでは?

0 件のコメント: