CLOVER🍀

That was when it all began.

Apache VelocityのScalaラッパーを書いてみました

ちょっと思い立って、Apache Velocity向けのScalaラッパーライブラリを書いてみました。

Velocity4s
https://github.com/kazuhira-r/velocity4s

名前に、何のひねりもありません。あと、単にソースをGitHubに置いているだけなので、あんまり意味ないでしょうけど。使い方はREADMEを参照。

こういったテンプレートに対して、

      val templateAsString = """|$person.name
                                |$person.age
                                |
                                |#foreach ($e in $list)
                                |$e
                                |#end
                                |
                                |#foreach ($k in $map.keys())
                                |$map[$k]
                                |#end
                                |
                                |#foreach ($v in $some)
                                |some($v)
                                |#end
                                |#foreach ($v in $none)
                                |none
                                |#end
                                |
                                |""".stripMargin
      val templateName = "template.vm"

ScalaのコレクションやOptionをforeachが解釈できるようにしたり

      val context = new VelocityContext
      context.put("person", Person("Taro", 20))
      context.put("list", List("Java", "Scala", "Groovy", "Clojure"))
      context.put("map", Map("key1" -> "value1", "key2" -> "value2"))
      context.put("some", Some("hello"))
      context.put("none", None)

(結果)

Taro
20

Java
Scala
Groovy
Clojure

value1
value2

some(hello)

Mapに対するキーアクセスを、JavaのMapのように扱えます。

     val templateAsString = """$map["key"]"""

裏では、Map#getOrElse(key, null)に置き換わっていますが…。

プロパティアクセスも、一応OKです。

      val templateAsString = "Hi, My name is $person.name!, $person.age years old"

マッピングするCase Class。

case class CasePerson(name: String, age: Int)

これで、Case Classのメンバーにアクセスできます。通常のクラスのvalなども同様です。

が、なんとなく思い立って書いてみたはいいものの、Velocityテンプレート上ではScalaで使えるはずの表現力がかなり落ちてしまうため、まあ難しいですね。それにこのアプローチ自体も、ScalaのライブラリをJavaに寄せるという形ですので。

需要なさそう(笑)。

まあ、個人的な練習を兼ねていますので、適当にメンテしてるかもしれません。

ちなみに最初の元ネタはここでした。
Velocity Plugin for Play2 framework
https://github.com/Furyu/play-velocity-plugin

が、Playのプラグインになっているし、いざ書いてみるともうちょっといろいろ書いてみたくなって結果こんな感じになりました。個人的にはFreemarkerよりもVelocityの方が見通しやすいです。

今回、ScalaのクロスビルドやTravis CIを初めて使いました。これはこれで、いろいろ勉強になりましたー。