Play 2.0 用户指南 - 模版引擎 -- 针对Scala开发者

Stella981
• 阅读 540

一个基于Scala的类型安全的模版引擎

    Play2.0带来了一个全新的真正强大的基于Scala的模版引擎。该引擎的设计灵感源于ASP.NET Razor.特别是:

        简洁,富有表达力,流畅:最小化语法字符和击键要求,让你快速,流畅的编写代码。不像大多数模版引擎的语法,你无须明确的中断HTML代码就可嵌入服务器端逻辑。引擎会智能 的为你识别。这是一个真正简洁,富有表达力的语语法,使输入变得干净,快速,愉快。

        易于学习:掌握简单的概念就能让你快速产出。它使用你已掌握的Scala和HTML技能。
        非新语言:我们极力避免创造一门新语言。相反,我们想使开发人员能够利用其现有的Scala语言技能,在你选择的语言下提供一个HTML结构工作流程的模板标记语法。
        可使用任何文本编辑器:不需要特别的编辑工具,旧的文本编辑器也可轻松工作。

    模版会被编译,因此你可以在浏览器中看到任何编译错误。
Play 2.0 用户指南 - 模版引擎 -- 针对Scala开发者    

概述

    Play Scala 模版是简单的文本文件,它包含简短的Scala代码块。它可以生成任何的文本格式,HTML,XML,CVS。
   模版系统已被设计成可以自然舒适的处理HTML,使得web设计师们能轻松的工作。

    模版会被编译成标准的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)

语法:充满魔力的‘@’字符

    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)

    甚至一个隐式参数:     

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

迭代

    你可以使用 Scala 的for-comprehension,以很表标的方式。但注意,编译器会自动在你的代码块前面加上 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) => {
    <span class="admin">Connected as admin (@name)</span>
  }

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

    定义可重用块

    你可以定义可重用代码块:

@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>

    注意:这种方式声明的代码块某些时候可能很有用,但谨记,模块不是一个编写复杂逻辑的好地方。它通常都应该提取到外部的Scala文件中。(如果你愿意,出可以保存在views/目录中)

    依照惯例,以 implicit 开头的可重用块会被标记为 隐式的:

@implicitFieldConstructor = @{ MyFieldConstructor() }

    声明可重用值

    你可以使用 define 定义范围变量值:

@defining(user.firstName + " " + user.lastName) { fullName =>
  <div>Hello @fullName</div>
}

    导入声明

    你可以在模版开头(或子模块)处按需导入声明:

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

    注释

    在服务器端编写注释,你可以使用 @* *@:

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

    你可以在第一行编写注释以Scala API的形式文档化该模版。

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

<h1>@msg</h1>

    转义

    默认情况下,内容的动态部分会依照模版的类型转义(如 HTML,XML)。如果你需要输出原生的内容,请在模版中用模版内容类型包装。

    如输出原始的HTML    

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

   Scala模版的常见用例

    模版,作为普通函数,可通过任何方式组合。下面是一些常用的场景例子。

    布局

    让我们声明一个 views/main.scala.html 模版,它將作为主要布局模版: 

@(title: String)(content: Html)
<!DOCTYPE html>
<html>
  <head>
    <title>@title</title>
  </head>
  <body>
    <section class="content">@content</section>
  </body>
</html>

    你看到,该模版需要两个参数:title 和 Html 内容块。我们可以在另一个 views/Application/index.scala.html 中使用它:

@main(title = "Home") {
    
  <h1>Home page</h1>
    
}

    注意:我们有时命名参数为@main(title = "Home"),有时候为@main("Home")。依你所好,在不同的场景中选择更简洁的形式。

    有时候,你需要另一个页面特定的内容,例如边栏或者页脚。你可以指定另一个参数:

@(title: String)(sidebar: Html)(content: Html)
<!DOCTYPE html>
<html>
  <head>
    <title>@title</title>
  </head>
  <body>
    <section class="sidebar">@sidebar</section>
    <section class="content">@content</section>
  </body>
</html>

    在我们的'index'模版中使用它,需要:

@main("Home") {
  <h1>Sidebar</h1>

} {
  <h1>Home page</h1>

}

    另外,我们可以单独声明边栏:

@sidebar = {
  <h1>Sidebar</h1>
}

@main("Home")(sidebar) {
  <h1>Home page</h1>

}

    标签(它们也不过是函数,不是吗?)

    让我们编写一个简单的 views/tags/notice.scala.html 标签,显示HTML通知:

    现在,让我们在另一个模版中使用它:

@(level: String = "error")(body: (String) => Html)
 
@level match {
    
  case "success" => {
    <p class="success">
      @body("green")
    </p>
  }

  case "warning" => {
    <p class="warning">
      @body("orange")
    </p>
  }

  case "error" => {
    <p class="error">
      @body("red")
    </p>
  }
    
}

    包含

    同样,这也没什么特别。你可以调用任何你需要的模版(实际上是来自任何地方的函数都可以):

<h1>Home</h1>
 
<div id="side">
  @common.sideBar()
</div>
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
java中比较两个时间的差值
项目背景1.某篇文稿的发布时间是publishDate,例如:2020072118:00:41。2.现要求判断该篇文稿的发布时间是否在近30天之内。publicstaticlongdayDiff(DatecurrentDate,DatepublishDate){LongcurrentTimecurrentDat
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这