« Bone head | Main | Sun Web Developer... »

Pluggable renderers and scripting languages in Roller

My next ApacheCon talk is about Roller and blogs as a web development platform. One of the things I plan to discuss is using scripting languages within Roller, something that's possible now because Roller versions 3.0 and later allows pluggable renderers. It's undocumented and a little hacky right now, but by plugging in your own custom renderers you can add support for new template and scripting languages as alternatives to Roller's built-in Velocity. Here are some notes on the whys and hows.

Why would you want to plugin a new scripting or template language?

I can think of two reasons you might want to plug-in a new renderer to Roller. If you're not happy with Velocity and want to plugin an alternative template language like Freemarker you can do it with a custom renderer. Or, if you're developing sophisticated Roller templates and you need a more sophisticated programming language like Groovy, JRuby or Javascript then custom renderers are your best bet.

What can you do in an alternative scripting or template language?

In an alternative template or scripting language you can access the normal Roller model objects (see the Roller Template Guide for a reference) and you can generate just about any type of content you want. However, you cannot access the Roller macros because they're written in and require Velocity.

It's also worth noting that you can get in quite a bit of trouble with an alternative language. Roller's built-in Velocity renderer allows users to access only a very limited set of objects, but other scripting and template languages might not be so safe. That's why you might not want to make all plugin renderers available to all of your users.

How do you implement scripting in a plugin renderer?

I plan on documenting the process at some point, but basically you implement two simple interfaces: RendererFactory and Renderer. So far, I've developed three plugin renderers: BSFRenderer, GroovletRenderer and GSPRenderer. Let's discuss each so you can see how they work.

A BSFRenderer example

The Bean Scripting Framework (BSF)  makes it easy to call a wide variety of scripting languages from Java and because it works with Java SE 5, it's a better choice for Roller than the Java SE 6 scripting extensions. I developed a BSF renderer (BSFRendererFactory and BSFRenderer) and with it, it's theoretically possible to support the use of just about any BSF scripting language in a Roller template. I've tried Groovy and JavaScript and they both work fine, but JRuby has some conflicts with the version of Hibernate that we're using in Roller so I'll have to revisit JRuby later.

Unfortunately, with the BSFRenderer you're stuck writing Servlet-like code like this Groovy example:

    out.println("<html><body>")
    out.println("Hello World, my blog is ${model.weblog.name}");
    out.println("</body></html>");

Ugh. Nothing to write home about, that's for sure. Fortunately, there's something better.

A GroovletRenderer example

I also developed a GroovletRenderer and a Groovy Server Pages (GSP) GSPRenderer, which look more promising. These renderers call Groovy directly and behave like the Groovlet and Groovy Template Servlets that come with Groovy.

With my new GroovletRenderer (GroovletRendererFactory and GroovletRenderer), you can use the GroovyMarkup builder to build HTML. Here's an example that displays a blog title, description and most recent entries:

    html.html { // html is implicitly bound to new MarkupBuilder(out)
        head {
            title(model.weblog.name)
        }
        body {
            h1(model.weblog.name)
            i(model.weblog.description)
            map = model.getWeblogEntriesPager().getEntries();
            map.keySet().each() {
               map.get(it).each() {
                  h2(it.title)
                  p(it.text)
                  br()
               }
            }
        }
    }

Starting to look more interesting, no?

A GSPRenderer example

I also developed a GSPRenderer (GSPRendererFactory and GSPRenderer), which allows you to use a JSP like syntax with <% %> and <%= %>. Here's the above example, but rewritten as a Roller GSP page:

    <html>
       <head>
          <title>${model.weblog.name}</title>
       </head>
       <body>
       <h1>${model.weblog.name}</h1>
       <i>${model.weblog.description}</i>
       <% map = model.getWeblogEntriesPager().getEntries();
          map.keySet().each() { %>
              <% map.get(it).each() { %>
                <h2>${it.title}</h2>
                <p>${it.text}</p><br />
              <% }
          }%>
       </body>
    </html>

That's all I have time for tonight. Next I hope tackle JRuby and hopefully I'll find some way to support some form of JRuby templating too. Where is all this going? I don't know. I'm not sure these plugins will make it into the Roller 4.0 release, but I do hope to make it easier to drop them and renderer plugins like them into Roller 4.0.

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed

« Bone head | Main | Sun Web Developer... »

Welcome

This is just one entry in the weblog Blogging Roller. You may want to visit the main page of the weblog

Related entries

Below are the most recent entries in the category Roller, some may be related to this entry.