Scalatra-Scalate 3. Templates

Robert Crowther Apr 2022

PrevNext

Well, the previous step was… cute. But not much can be made this way. What we need now is to show how code can be brought in. Worth knowing—Scala can interface to any Java library—same engine, and the API has been carefully designed to do this. Also worth thinking on, someone once said to me that one of the advantages of Java, bicker aside, is that it has ‘acres of good code’.

I could go any direction here. Importing databases, rolling special outputs like JSON, enabling search engines etc. Nope, straightforward, I go templating. What I describe here can be applied to other code imports. Incidentally, if you were heading in the direction of JSON, Scalatra has the Jackson JSON library and JSON4s multi‐library JSON API ready‐imported—go look at those.

Templates, Scalate

Straight away, you’ll find there are multiplicities. There’s many templating engines written in Java. Perhaps you stumble across ‘Scalte’ because it’s referenced on the website. There is reason—Scalate shares some coders with Scalatra. But those people are not interested in telling you that. There’s something else, too. Scalate is a templating engine, but has several templating languages.

Ah, but Scalte has no instructions for integrating into Scalatra. Instead, it seems the template code itself has a Jetty server builtin. The advice on the Scalate website suggests you work through that. But, with a brand‐new Scalatra up and running, that’s not what we want to do. I’m convinced enough of your goodness, guys, to ask for a the spanner. Right, this is going to get tricky. How do we get this code into a Scalatra? No instructions on the SBT website, either. And the Scalatra website has one broken link. Out of resource. It’s got to be through the build tool, yes?

What you do is go to Maven Central. It’s not the only repository for Java, but Maven is Java’s build tool, and a good start. Then look up Scalate, maybe Scalatra. Lo, there is a thing called ‘scalatra‐scalate’. And I’m going to guess, so long as what is there is modern, that code listed there will download Scalte for me, then integrate into Scalatra (don’t ask me how I know, I don’t, but Java‐world is like this).

Maven Central gives me a handy line to configure SBT,

// https://mvnrepository.com/artifact/org.scalatra/scalatra-scalate
libraryDependencies += "org.scalatra" %% "scalatra-scalate" % "2.8.2"

Honestly, if I had not done this before I would despair—where does that go? How do I use it? Well, remember,

/pathToTheProject/ProjectName/build.sbt

Yes? Here we go,

.settings(
  ...
  libraryDependencies ++= Seq(
    ...
    "javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided",
    "org.scalatra" % "scalatra-scalate_2.13" % "2.8.2"
    ),
)

Ok, try running or provoking SBT. It will deluge. Or something it provokes will deluge. If you got that, go look at the library directory. It’s satisfyingly full of lumps called ‘scalate’.

Now a question. How do I get this capability into the Servlet code area? Again, no instructions. Take it from me, you remember how we gave a URL for our project? Well, backwards—‘reversed’—URLs is how Java namespaces projects. As usual with Java, reliable and silly. So the import must be something like that. Take it from me, it’s this,

import org.scalatra.scalate._

The funny underscore is another Scala thang, it means ‘import everything’.

Using the code

I stand that this section is only for those who use Scalate, but anyway… For various historical and dramatic reasons, Java core code is the best‐documented code in the business. In an attempt to compensate, Java non‐core code is some of the worst (though some may make a case for LISP and C codebases). Anyway, you can’t hold this against the Scalatra coders and maintainers. They work in a difficult environment, and they’ve put work in. Unfortunately, Scalate—direct from SBT/Scalatra—is off‐grid. We already had problems with import, or I did. Sure we must summon a template? Probably passing parameters. How? And where to put the template? In the welter of options and configurations, no generic instruction.

Twirl

Right I’m dragging you through this. Casting wide, I found there was in my scaffold a template for the Twirl templating engine. Didn’t match the instructions, but never mind. To summon, this worked,

import views._
...

get("/twirl") {
    views.html.hello.render()
}

At last. A template rendered. Which uses also the supplied layout template.

Scalate

I was at a loss for examples and near‐surrendered here. Then, not on Scalte but Scalatra pages, found the page on views, That left me with only one hole in understanding, which was, where is ScalateSupport imported from? It’s not demonstrated, because it’s a Java/C idiom that documentation never illustrates imports. Guesswork suggested this,

import org.scalatra.scalate._

Well, at least I have some idea where the templates need to go,

WEB-INF/templates/views/index.ssp

Containing a snippet I found somewhere else,

#for (i <- 1 to 3)
<p>${i}</p>
#end
<p>See, I can count!</p>

And I can use this to call, explicitly ensuring the path is right,

get("/") {
  layoutTemplate("/WEB-INF/templates/views/index.ssp")
}

And now I get somewhere. So then I try the ScalateSupport helper, which is an abbreviated form of the ‘layoutTemplate’ call given above,

get("/") {
  ssp("/index.ssp")
}

That worked also. Some cut and pasting confirmed more. ‘App Root’ means where Java Servlets build user code from—src/main/webapp/WEB‐ROOT. And the ScalateSupport helpers will find the ‘index.ssp’ file if it is in a directory called ‘views’. Key info: the engine I guess searches recursively, because it doesn’t matter how deep the ‘views’ folder is nested, in ‘templates/ssp’ or whatever, the engine finds the file.

End of Part Three

Yeh, this is Java‐world. Remember, it’s your fault. You’re to blame for this. Howerver, you got extra code in there. That may be enough. You may be up and running. Or you may not have taken enough yet. Part Four awaits.