Liz Douglass

Scalatra, Scalate and Scaml

with one comment

A while ago I set about creating a webapp for monitoring the status of the various Quartz jobs that we use to keep our main application ticking. It was put together quickly using Simple Build Tool and Scalatra. I needed a templating engine and noticed that Scalatra has support for Scalate (although at the time the support was only experimental). I decided to give it a try. The first step was to add the dependencies for Scalate and Scalatra-Scalate into our build file:

val scalatraScalate = "org.scalatra" % "scalatra-scalate_2.8.0" % "2.0.0.M1"
val scalateCore = "org.fusesource.scalate" % "scalate-core" % "1.2"

I soon ran into the Scalatra issue with using Scalate and Logback and instead decided to use Scalate on its own. Referring to the Scalate Embedding Guide, I created an instance of the Scalate TemplateEngine class in a trait that is extended by my Scalatra servlet:

trait ScalateTemplateEngine {
   def render(templatePath: String, context: Map[String, Any], response: HttpServletResponse) = {
       val templateEngine = new TemplateEngine
       val template = templateEngine.load(templatePath)

       val buffer = new StringWriter()
       val renderContext = new DefaultRenderContext(templateEngine, new PrintWriter(buffer))

      context.foreach({case (key, value) => renderContext.attributes(key) = value})
      template.render(renderContext)

      response.getWriter.write(buffer.toString)
   }
}

Then, referring to this excellent blog post, I created an index.scaml file. The scaml file (below) is concise and reasonably readable. The only hiccups I encountered in making it were:

  1. Figuring out the syntax and correct indenting of the for loop
  2. Realising that all the values the map are automatically converted to Options (hence the many get calls).
-@ val title: String = "Scheduler"
-@ val header: String = "Scheduler"
-@ val quartzStatus: String = "No quartz status information available"
-@ val scheduledTasks: List[Map[String, String]] = Nil
-@ val quartzInformation: String = "No quartz information available"
!!! 5
%html
  %head
    %title= title
  %body
    %h1
      != header
    %h5
      != quartzStatus

    %table{:border => 1}
      %thead
        %td Task
        %td Status
        %td Quantity
        %td Last Attempt Start Time
        %td Last Attempt Finish Time
        %td Last Successful Run Start Time
        %td Last Successful Run Finish Time
        %td Last Error
        %td Action
      = for(scheduledTask <- scheduledTasks)
        %tbody
          %td= scheduledTask.get("name").get
          %td= scheduledTask.get("status").get
          %td= scheduledTask.get("quantity").get
          %td= scheduledTask.get("lastRunStart").get
          %td= scheduledTask.get("lastRunFinish").get
          %td= scheduledTask.get("lastSuccessStart").get
          %td= scheduledTask.get("lastSuccessFinish").get
          %td= scheduledTask.get("lastException").get
          %td
            %form(method="post")
              %input(type="submit" name={scheduledTask.get("action").get} value="Run now")
Advertisements

Written by lizdouglass

December 15, 2010 at 9:22 am

Posted in Uncategorized

Tagged with , ,

One Response

Subscribe to comments with RSS.

  1. note that you can use the Map.apply() method in Scala to avoid using the get() method which returns an Option. So

    scheduledTask.get(“lastRunFinish”).get

    can be

    scheduledTask(“lastRunFinish”)

    jastrachan

    December 15, 2010 at 12:26 pm


Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: