Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mustache Scalate vs Mustache Java

I need to pick a Mustache rendering engine for a Scala project of mine. Seems like the only two choices are Mustache-Java and Scalate? Are there any comparisons? Which one is the more stable/performant of the two?

like image 490
Nej Kutcharian Avatar asked Jan 17 '12 03:01

Nej Kutcharian


People also ask

What is Java mustache?

Mustache is a simple web template system. It is available for many programming languages including Java. Mustache is described as a logic-less because it does not have any explicit control flow statements, such as if and else conditionals or for loops.

What is mustache JS used for?

Mustache is an open source logic-less template engine developed for languages such as JavaScript, Ruby, Python, PHP, Java and many more. It's a very lightweight, readable syntax with a comprehensive specification. Mustache can be used for HTML, config files, and source code.

How do you comment on a Moustache?

You are trying to comment on mustache template that also has html in it, so you actually have to add mustache comment where the mustache code is and html comment where the html code is.

What is spring boot mustache?

Overview. In this article, we'll focus on using Mustache templates for producing HTML content in Spring Boot applications. It's a logic-less template engine for creating dynamic content, which is popular due to its simplicity. If you want to discover the basics, check our introduction to Mustache article.


3 Answers

I just went through this same process (Mustache Scalate or Mustache Java). I ended up going with Mustache Java, and it's working fine.

Why Mustache Java? Because all I wanted was Mustache templates. Scalate has more than just this support, and I didn't want to add more "stuff" to my code base but only use part of its functionality.

like image 127
Tim Holt Avatar answered Oct 19 '22 23:10

Tim Holt


I was using mustache as part of scalatra-scalate. This is the only sensible choice for me as I'm already invested in Scalatra. Given the choice, I'd try mustache-java thoroughly. The Scalate engines are (still?) somewhat quirky and immature.

A few examples I ran into:

  • if you modify the default delimiters {{=<% %>=}} you will have to add spaces around your delimiters from then on, otherwise the parser chokes
  • if you want to plug custom handling for missing keys, you're stuck
  • sometimes the rendering hangs for minutes at a time for no obvious reason (this was with Jade, not Mustache, but it's rather scary anyway)

If you're not doing complex things mustache works fine though, and Scalate adds some nifty features like default templates and such that might help you.

like image 37
iwein Avatar answered Oct 19 '22 21:10

iwein


I just went through this ordeal and in as much as I wanted to use scalate since I'm using Scala, I ended up using Mustache-Java for two reasons:

  1. There is no trivial way to load template from /resources dir in classpath (or even just the normal Java stream objects). This seems very basic and I'm baffled why this is not available OOB.
  2. Similar to #1, there is no trivial way to load template from a simple String. You also need to write a custom loader if you want to do it. Why?

This is based on their documentation. Scalate looks very powerful and flexible if you're using it to generate server-side web pages, but for simple use cases, it incurs too much baggage.

One thing I discovered in Mustache-Java, is that you need to convert the data into Java map or it doesn't work (at least with 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"))
}

Inverted sections work:

"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"))
}

Finally, regarding lists: case classes are supported but for any list fields, they have to be the Java types. The following variations should work:

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"))
}
like image 29
Dexter Legaspi Avatar answered Oct 19 '22 22:10

Dexter Legaspi