16

我需要为我的 Scala 项目选择一个 Mustache 渲染引擎。似乎只有 Mustache-Java 和 Scalate 两个选择?有比较吗?两者中哪一个更稳定/性能更好?

4

5 回答 5

6

我刚刚经历了同样的过程(Mustache Scalate 或 Mustache Java)。我最终选择了 Mustache Java,它运行良好。

为什么要使用小胡子 Java?因为我想要的只是 Mustache 模板。Scalate 不仅有这种支持,而且我不想在我的代码库中添加更多“东西”,而只想使用它的部分功能。

于 2012-04-04T16:24:34.260 回答
3

我使用 mustache 作为 scalatra-scalate 的一部分。这对我来说是唯一明智的选择,因为我已经投资了 Scalatra。如果可以选择,我会彻底尝试 mustache-java。Scalate 引擎(仍然?)有些古怪和不成熟。

我遇到的几个例子:

  • 如果您修改默认分隔符 {{=<% %>=}} 从那时起您将不得不在分隔符周围添加空格,否则解析器会阻塞
  • 如果你想为丢失的键插入自定义处理,你会被卡住
  • 有时渲染会无缘无故地一次挂起几分钟(这是 Jade,而不是 Mustache,但无论如何它都相当可怕)

如果您不做复杂的事情,mustache 可以正常工作,Scalate 添加了一些漂亮的功能,如默认模板等,这可能会对您有所帮助。

于 2012-01-25T19:34:53.030 回答
2

我刚刚经历了这个磨难,因为我使用的是 Scala,所以尽管我想使用 scalate,但我最终使用Mustache-Java有两个原因:

  1. 没有简单的方法可以从/resources类路径中的 dir 加载模板(甚至只是普通的 Java 流对象)。这似乎很基本,我很困惑为什么这不可用 OOB。
  2. 与 #1 类似,没有简单的方法可以从简单的String. 如果你想这样做,你需要编写一个自定义加载器。为什么?

这是基于他们的文档。如果你用它来生成服务器端的网页,Scalate 看起来非常强大和灵活,但对于简单的用例,它会带来太多的包袱。

我在 Mustache-Java 中发现的一件事是,您需要将数据转换为 Java 映射,否则它不起作用(至少在 Scala 2.12 中):

"Mustache test" should "succeed" in {
  import scala.collection.JavaConverters._

  val template = "Hello, {{name}}"
  val mf = new DefaultMustacheFactory()
  val mustache = mf.compile(new StringReader(template), "sample")
  val map = Map("name" -> "Joe")

  val sw = new StringWriter()
  mustache.execute(sw, map.asJava) // if you don't use .asJava here it's not going to work

  assert(sw.toString.contains("Joe"))
}

倒置部分工作:

"Mustache test exclusion" should "succeed" in {
  import scala.collection.JavaConverters._

  val template = "Hello, {{^exclude}}am I excluded?{{/exclude}}"
  val mf = new DefaultMustacheFactory()
  val mustache = mf.compile(new StringReader(template), "sample")
  val map = Map("exclude" -> true)

  val sw = new StringWriter()
  mustache.execute(sw, map.asJava)

  assert(!sw.toString.contains("excluded"))
}

最后,关于列表:支持案例类,但对于任何列表字段,它们必须是 Java 类型。以下变体应该有效:

case class Plan(name: String, 
                currency: String, 
                price: String)

"Mustache test with object context with list" should "succeed" in {
  import scala.collection.JavaConverters._
  import java.util.{List => JavaList}

  val template =
    """{{#plans}}
      |Name: {{name}}
      |Price: {{currency}}{{price}}
      |{{/plans}}""".stripMargin
  val mf = new DefaultMustacheFactory()
  val mustache = mf.compile(new StringReader(template), "sample")
   
  // note the Java list type here
  case class Plans(plans: JavaList[Plan]) 
  val plans = Plans(Seq(Plan("essential", "$", "30")).asJava)
  val sw = new StringWriter()
  mustache.execute(sw, plans)

  val list = Seq(Plan("essential", "$", "30")).asJava
  mustache.execute(sw, Map("plans" -> list).asJava)

  assert(sw.toString.contains("Name"))
}

"Mustache test with list" should "succeed" in {
  import scala.collection.JavaConverters._

  val template =
    """{{#plans}}
      |Name: {{name}}
      |Price: {{currency}}{{price}}
      |{{/plans}}""".stripMargin
  val mf = new DefaultMustacheFactory()
  val mustache = mf.compile(new StringReader(template), "sample")
   
  val sw = new StringWriter()

  // do not forget .asJava here
  val list = Seq(Plan("essential", "$", "30")).asJava 

  // do not forget .asJava here
  mustache.execute(sw, Map("plans" -> list).asJava) 

  assert(sw.toString.contains("Name"))
}
于 2021-03-13T15:42:08.247 回答
0

Mustache-Java 的一个好处是相对于 Scala,Java 的编译速度非常快。

于 2012-01-17T20:08:57.433 回答
0

Scalate 使渲染 Mustache 模板变得容易,我宁愿使用相对直观的 Scala 库而不是 Java 库。

假设您有以下simple_example.mustache模板:

I like {{programming_language}}
The code is {{code_description}}

您可以使用以下代码呈现模板:

import org.fusesource.scalate.TemplateEngine
val sourceDataPath = os.pwd/"simple_example.mustache".toString
val engine = new TemplateEngine
val someAttributes = Map(
  "programming_language" -> "Scala",
  "code_description" -> "pretty"
)
engine.layout(sourceDataPath, someAttributes)

结果如下:

I like Scala
The code is pretty
于 2020-12-22T03:00:25.347 回答