【问题标题】:Why did Playframework 2 use a custom Scala Template Engine instead of scalas build in xml mode?为什么 Playframework 2 使用自定义 Scala 模板引擎而不是 scalas 以 xml 模式构建?
【发布时间】:2012-06-01 14:51:52
【问题描述】:

Play 2.0 使用基于 scala 的自定义模板引擎,允许在 html 代码中使用 scala 的子集。

为什么做出这个设计决定而不是使用 scalas 内置 xml 模式?

播放模板引擎有一些缺点,比如

  • 仅支持 scala 的一个子集,例如,似乎无法在函数内部定义函数
  • eclipse 不支持编辑器

另一方面,我知道 play scala 模板引擎支持非格式良好的 html,这在 scalas xml 模式下是不可能的,但我想应该总是可以以格式良好的方式编写模板大大地。我只是 play 和 scala 的初学者,只是想了解上下文。

【问题讨论】:

    标签: template-engine playframework-2.0 design-decisions


    【解决方案1】:

    我认为它有几个答案:

    1. 这是一个模板。模板不应该包含复杂的逻辑。所有逻辑操作都必须在控制器/模型中完成。

    2. 模板可以具有您想要的任何格式:电子邮件、CSV、SQL 等。将模板限制为有效的 XML 确实限制了框架的可能性。

    3. 一切都是可编译的。甚至路由、资产、模板继承等。为了让这些机制与框架的其余部分一起工作,可能必须做出一些选择。但是没有人能比框架的创建者更好地回答你。

    【讨论】:

    • to 1) 我完全同意模板不应该包含太多逻辑,但有时即使对于短代码部分,拥有完整的权力也是很好的,所以这个决定应该留给程序员。
    • to 2) 这是一个很好的观点。另一方面,我猜在 80% 的实际案例中都需要 html 或 xml。另外 19% 可能是 json,并且 play 提供了比模板更好的方式。对于其余的(csv,sql,...),也许其他方式更适合 csv 库,对于 0.1% 的用例,其中一个人真的需要非常特殊和复杂的基于文本的模板,我想可以使用另一个播放模板引擎模块。
    • to 3) scala 支持我猜想的所有这些功能
    • (在 play api 的上下文中)
    【解决方案2】:

    一个原因可能是 scala 中 xml 中属性的笨拙处理。有两个问题:

    1. “selected”等属性必须存在或不存在
    2. 像输入帮助模板的 htmlArgs 一样动态添加属性列表

    一个简单的 scala 示例说明了困难:

    def addAttributes(element: Elem, attributes: Map[Symbol, _ <: Any]): Elem = {
        var el = element
        for ((key, value) <- attributes) el = el % Attribute(None, key.name, Text(value.toString), Null)
        el
      }
    
      def multiselect[T](field: play.api.data.Field,
        options: Seq[T],
        optionValue: T => String,
        optionText: T => String,
        args: (Symbol, Any)*)(implicit handler: FieldConstructor, lang: play.api.i18n.Lang) = {
        val values = { field.indexes.map { v => field("[" + v + "]").value } }
        input(field, args: _*) {
          (id, name, value, htmlArgs) =>
            Html(
              addAttributes(
                <select id={ id } name={ name } multiple="multiple">
                  {
                    options.map { v =>
                      val z: Option[String] = if (values contains v) Some("selected") else None
                      <option value={ optionValue(v) } selected={ z map Text }>{ optionText(v) }</option>
                    }
                  }
                </select>,
                htmlArgs).toString)
        }
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多