Created
March 28, 2018 00:51
-
-
Save abhandaru/a29799db9f669421d77410d9f2c1f399 to your computer and use it in GitHub Desktop.
Minimal mustache-scala string template example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import collection.JavaConverters | |
import com.github.mustachejava.reflect.ReflectionObjectHandler | |
import com.github.mustachejava.{DefaultMustacheFactory, Iteration, MustacheFactory} | |
import java.io.{StringReader, StringWriter, Writer} | |
import java.lang.reflect.{Field, Method} | |
import java.util.{List => JList} | |
import runtime.BoxedUnit | |
import scala.reflect.ClassTag | |
object Mustache { | |
private[util] val Factory: MustacheFactory = { | |
val mf = new DefaultMustacheFactory | |
mf.setObjectHandler(ScalaObjectHandler) | |
mf | |
} | |
} | |
case class MustacheTemplate(template: String) { | |
val innerTemplate = Mustache.Factory.compile(new StringReader(template), "tmp") | |
def apply(context: Any): String = { | |
val writer = new StringWriter | |
innerTemplate.execute(writer, context) | |
writer.flush | |
writer.toString | |
} | |
} | |
/** | |
* Adapted from here: | |
* https://github.com/spullara/mustache.java/blob/master/scala-extensions/scala-extensions-2.11/src/main/scala/com/twitter/mustache/ScalaObjectHandler.scala | |
*/ | |
object ScalaObjectHandler extends ReflectionObjectHandler { | |
import JavaConverters._ | |
override def checkMethod(member: Method) {} | |
override def checkField(member: Field) {} | |
override def coerce(value: AnyRef) = { | |
value match { | |
case m: collection.Map[_, _] => mapAsJavaMap(m) | |
case u: BoxedUnit => null | |
case Some(some: AnyRef) => coerce(some) | |
case None => null | |
case _ => value | |
} | |
} | |
override def iterate(iteration: Iteration, writer: Writer, value: AnyRef, scopes: JList[AnyRef]) = { | |
value match { | |
case TraversableAnyRef(t) => { | |
var newWriter = writer | |
t foreach { | |
next => | |
newWriter = iteration.next(newWriter, coerce(next), scopes) | |
} | |
newWriter | |
} | |
case n: Number => if (n.intValue() == 0) writer else iteration.next(writer, coerce(value), scopes) | |
case _ => super.iterate(iteration, writer, value, scopes) | |
} | |
} | |
override def falsey(iteration: Iteration, writer: Writer, value: AnyRef, scopes: JList[AnyRef]) = { | |
value match { | |
case TraversableAnyRef(t) => { | |
if (t.isEmpty) { | |
iteration.next(writer, value, scopes) | |
} else { | |
writer | |
} | |
} | |
case n: Number => if (n.intValue() == 0) iteration.next(writer, coerce(value), scopes) else writer | |
case _ => super.falsey(iteration, writer, value, scopes) | |
} | |
} | |
val TraversableAnyRef = new Def[Traversable[AnyRef]] | |
class Def[C: ClassTag] { | |
def unapply[X: ClassTag](x: X): Option[C] = { | |
x match { | |
case c: C => Some(c) | |
case _ => None | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment