Documentation

You are viewing the documentation for the 2.2.0 release in the 2.2.x series of releases. The latest stable release series is 2.4.x.

§テンプレートエンジンに対するカスタムフォーマットのサポートの追加

組み込みのテンプレートエンジンは一般的なテンプレートフォーマット (HTML、XML、等) をサポートしていますが、必要であれば独自のフォーマットのサポートを簡単に追加する事ができます。このページではカスタムフォーマットをサポートする為に必要なステップをまとめています。

§テンプレートプロセスの概要

テンプレートエンジンはテンプレートの静的および動的な部品を結合する事でビルドします。例えば以下のテンプレートを考えてみて下さい:

foo @bar baz

上記のテンプレートは一つの動的な部品 (bar) およびその周囲の二つの静的な部品 (foo および baz) から構成されています。テンプレートエンジンはこれらの部品を結合する事で結果をビルドします。実際には、クロスサイトスクリプティング攻撃を防ぐ為、他の部品と結合される前に bar の値をエスケープすることができます。このエスケーププロセスはフォーマット毎に特有となります: 例えば、 HTML の場合は「<」を「&lt;」に変換したくなるでしょう。

テンプレートエンジンはどのようにしてテンプレートファイルに対応するフォーマットを知る事が出来るのでしょうか? 拡張子を見ています: 例えば、 .scala.html で終わる場合は、HTML フォーマットとファイルを紐付けます。

最終的に、テンプレートファイルを HTTP レスポンスのボディとして使用したい事が普通だと思うので、テンプレートのレンダリング結果から Play の result をどうやって作成するかを定義しなければいけません。

まとめると、独自のテンプレートフォーマットをサポートするには、以下のステップを行う必要があります:

§フォーマットを実装する

play.templates.Format[A] トレイトを実装しましょう。このトレイトは raw(text: String): A および escape(text: String): A メソッドがあり、それぞれ静的および動的なテンプレートの部品を統合する為に使われます。

フォーマットの A 型パラメータは、例えば HTML のテンプレートには Html といったように、テンプレートのレンダリング結果の型を定義します。この型は play.templates.Appendable[A] のサブタイプである必要があり、各部品をどうやって結合するかを定義します。

利便性のため、 Play は play.api.templates.BufferedContent[A] 抽象クラスを提供します。このクラスは結果をビルドする為に play.templates.Appendable[A]StringBuilder を使って実装していて、また HTTP のレスポンスボディにシリアライズする方法を Play に知らせるために play.api.mvc.Content トレイトを実装しています (詳細はこのページの最後のセクションを見て下さい)。

つまり、二つのクラスを書く必要があります: 一つは (play.templates.Appendable[A] を実装する事で) 結果を定義したクラスで、もう一つは (play.templates.Format[A] を実装する事で) テキストの統合プロセスを定義したクラスです。例えば、 HTML フォーマットを定義するには以下のようにします:

// `Html` の結果の型です。 Play に `Html` の値から HTTP の結果を生成方法を知らせるために、
// `Appendable[Html]` ではなく `BufferedContent[Html]` を継承しています。
class Html(buffer: StringBuilder) extends BufferedContent[Html](buffer) {
  val contentType = MimeTypes.HTML
}

object HtmlFormat extends Format[Html] {
  def raw(text: String): Html = …
  def escape(text: String): Html = …
}

§ファイル拡張子をフォーマットと関連づける

テンプレートは、ビルドプロセスでアプリケーションのソース全体をコンパイルする直前に .scala ファイルにコンパイルされます。 sbt.PlayKeys.templatesTypes キーは Map[String, String] 型の sbt 設定で、ファイル拡張子とテンプレートフォーマットのマッピングを定義しています。例えば、もし HTML が Play で標準でサポートされていなかった場合、以下のようにビルドファイルに書く事で .scala.htmlplay.api.templates.HtmlFormat フォーマットに関連づける必要があります:

templatesTypes += ("html" -> "play.api.templates.HtmlFormat")

矢印の右側には play.templates.Format[_] の値の完全修飾名が含まれている事に注意して下さい。

§テンプレート結果の型から HTTP の結果を生成する方法を Play に教える

暗黙の play.api.http.Writeable[A] の値がある場合、 Play は任意の A の値に対して HTTP レスポンスを書く事が出来ます。従って、あなたがやらなければいけない事はテンプレート結果の型に対してそのような値を定義する事です。例えば、以下は HTTP に対してそのような値を定義しています:

implicit def writableHttp(implicit codec: Codec): Writeable[Http] =
  Writeable[Http](result => codec.encode(result.body), Some(ContentTypes.HTTP))

ノート: テンプレート結果の型が play.api.templates.BufferedContent を継承している場合、やらなければいけないのは
暗黙の play.api.http.ContentTypeOf を定義する事です:

implicit def contentTypeHttp(implicit codec: Codec): ContentTypeOf[Http] =
  ContentTypeOf[Http](Some(ContentTypes.HTTP))

次: HTTP フォーム送信とバリデーション