【Play2.2】Scalaテンプレートファイル内に再利用可能なブロックを定義してみた
Play Framework 2.2 のScalaテンプレート(views/*.scala.html)内に、再利用可能ブロックを定義してみました。
まずはソース
app/views/index.scala.html
@(message: String) @jslink(js: String) = { <script src="@js" type="text/javascript"></script> } @title = @{ val head = "【テスト環境】" val appname = "hogehoge" head + appname } <!DOCTYPE html> <html> <head> <title>@title</title> <script src="@routes.Assets.at("javascripts/jquery-1.9.0.min.js")" type="text/javascript"></script> @jslink("http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js") @jslink(routes.Assets.at("javascripts/jquery-1.9.0.min.js").url) </head> <body> Hello World! </body> </html>
コンパイルされたScalaソース(target/scala-2.10/src_managed/main/views/html/index.template.scala)
package views.html import play.templates._ import play.templates.TemplateMagic._ import play.api.templates._ import play.api.templates.PlayMagic._ import models._ import controllers._ import java.lang._ import java.util._ import scala.collection.JavaConversions._ import scala.collection.JavaConverters._ import play.api.i18n._ import play.core.j.PlayMagicForJava._ import play.mvc._ import play.data._ import play.api.data.Field import play.mvc.Http.Context.Implicit._ import views.html._ /**/ object index extends BaseScalaTemplate[play.api.templates.HtmlFormat.Appendable,Format[play.api.templates.HtmlFormat.Appendable]](play.api.templates.HtmlFormat) with play.api.templates.Template1[String,play.api.templates.HtmlFormat.Appendable] { /**/ def apply/*1.2*/(message: String):play.api.templates.HtmlFormat.Appendable = { _display_ { def /*3.2*/jslink/*3.8*/(js: String):play.api.templates.HtmlFormat.Appendable = {_display_( Seq[Any](format.raw/*3.24*/(""" <script src=""""),_display_(Seq[Any](/*4.16*/js)),format.raw/*4.18*/("""" type="text/javascript"></script> """)))};def /*6.2*/title/*6.7*/ = {{ val head = "【テスト環境】" val appname = "hogehoge" head + appname }}; Seq[Any](format.raw/*1.19*/(""" """),format.raw/*5.2*/(""" """),format.raw/*10.2*/(""" <!DOCTYPE html> <html> <head> <title>"""),_display_(Seq[Any](/*14.17*/title)),format.raw/*14.22*/("""</title> <script src=""""),_display_(Seq[Any](/*15.23*/routes/*15.29*/.Assets.at("javascripts/jquery-1.9.0.min.js"))),format.raw/*15.74*/("""" type="text/javascript"></script> """),_display_(Seq[Any](/*16.10*/jslink("http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"))),format.raw/*16.83*/(""" """),_display_(Seq[Any](/*17.10*/jslink(routes.Assets.at("javascripts/jquery-1.9.0.min.js").url))),format.raw/*17.73*/(""" </head> <body> Hello World! </body> </html>"""))} } def render(message:String): play.api.templates.HtmlFormat.Appendable = apply(message) def f:((String) => play.api.templates.HtmlFormat.Appendable) = (message) => apply(message) def ref: this.type = this } /* -- GENERATED -- DATE: Sat Dec 14 23:05:42 JST 2013 SOURCE: C:/usr/workspace/Java/playProject/app/views/index.scala.html HASH: 12d570f04484050ca0b144e2def00f478fac70d9 MATRIX: 774->1|868->21|881->27|977->43|1028->59|1051->61|1109->99|1121->104|1223->18|1251->97|1279->176|1366->227|1393->232|1460->263|1475->269|1542->314|1622->358|1717->431|1763->441|1848->504 LINES: 26->1|28->3|28->3|30->3|31->4|31->4|32->6|32->6|37->1|39->5|40->10|44->14|44->14|45->15|45->15|45->15|46->16|46->16|47->17|47->17 -- GENERATED -- */
出力されたHTML
<!DOCTYPE html> <html> <head> <title>【テスト環境】hogehoge</title> <script src="/assets/javascripts/jquery-1.9.0.min.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script> <script src="/assets/javascripts/jquery-1.9.0.min.js" type="text/javascript"></script> </head> <body> Hello World! </body> </html>
ざっくりとした解説
まず、Scalaテンプレートファイルの先頭で、2種類の再利用可能ブロックを定義しています。
@jslink(js: String) = { <script src="@js" type="text/javascript"></script> } @title = @{ val head = "【テスト環境】" val appname = "hogehoge" head + appname }
1つ目の「jslink」は中括弧の先頭に「@」が無いため『再利用可能なコードブロック』で、2つ目の「title」は中括弧の先頭に「@」がある為『再利用可能な Scala のコードブロック』となっています。
『再利用可能なコードブロック』
内容はScalaテンプレートに変換されています。
コンパイルされたScalaソースを見ると、<!DOCTYPE html>以下と同じような処理をされているようです。
実際、
@jslink(js: String) = { <script src="@js" type="text/javascript"></script> } @jslink("http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js") @jslink(routes.Assets.at("javascripts/jquery-1.9.0.min.js").url)
これが
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script> <script src="/assets/javascripts/jquery-1.9.0.min.js" type="text/javascript"></script>
こう変換されました。
『再利用可能な Scala のコードブロック』
内容はScalaコードそのものに変換されています。
コンパイルされたScalaソースを見ても、通常の関数定義に変換されているようです。
実際、
@title = @{ val head = "【テスト環境】" val appname = "hogehoge" head + appname } <title>@title</title>
これが
<title>【テスト環境】hogehoge</title>
こう変換されました。