Donnerstag, 4. September 2008

Using Groovy Builders in Sling

Sling is a new approach in web development. It is, amongst other, a thin REST layer onto a JCR repository.

Sling also makes use of the language neutral scripting features of the java platform. Out of the box, several scripting languages are supported, like javascript and jruby. Since Groovy does have JSR 223 support, it is rather easy to create a groovy module to be used inside Sling. The only pity is that the Groovy Scripting Engine is not available via maven. See this Jira issue for some hints on creating a Groovy OSGI-module for Sling.

The thing I like most about Groovy is the real cool builder support. Using the MarkupBuilder, it is a snap to generate HTML or XML documents. I personally started to like MarkupBuilder syntax more than the templating approach.

The first time I saw something similar was at a demonstration of the excellent Seaside framework, where everything, including layout, is done in smalltalk. I am not sure wether the Groovy builders have been inspired by smalltalk or even Seaside, but both are sexy (I cannot speak for Seaside, haven't had the chance to play with it).

Anyways, on to some comparisons:

First a piece of jsp:


<%@page import="javax.jcr.query.Query"%>
<%@page import="javax.jcr.NodeIterator"%>
<%@page import="javax.jcr.Node"%>

<%@taglib prefix="sling" uri="http://sling.apache.org/taglibs/sling/1.0"%>
<sling:defineobjects/>
<div class="blueprint detail">
<a href="">.details.html"><%= currentNode.getName() %></a>
<h2>Properties</h2>
<h2>Controls</h2>
<div id="List">
<%
String q = "/jcr:root"+currentNode.getPath()+ "//*[@sling:resourceType='secmanagment/control']";
Query query = currentNode.getSession().getWorkspace().getQueryManager().createQuery(q, "xpath");
NodeIterator result = query.execute().getNodes();
%>Total <%=result.getSize()%>
<ul><%
while(result.hasNext()) {
Node n = result.nextNode();
%><li><%
out.flush();
sling.include(n.getPath() + ".overview.html");
%> </li><%
}
%>
</ul>
</div>
<div class="new">
<form action="">/controls/" method="POST">
<input type="text" name="name" value="Name">
<input type="hidden" name="sling:resourceType" value="secmanagment/control">
<input type="hidden" name="jcr:primaryType" value="nt:unstructured">
<input type="submit" value="create">
</form>
</div>


The same using Groovy with MarkupBuilder:

import groovy.xml.MarkupBuilder
import javax.jcr.query.Query
import javax.jcr.NodeIterator
import javax.jcr.Node


def q = "/jcr:root${currentNode.path}//*[@sling:resourceType='secmanagment/controls']";
def query = currentNode.session.workspace.queryManager.createQuery(q, "xpath");
def result = query.execute().nodes;

def builder = new MarkupBuilder(out)
builder.div(class:"blueprint detail") {
a(class:"blueprint details", href:"${currentNode.path}.details.html", currentNode.name)
h2("Properties")
h2("Controls") {
ul(class:"List") {
result.each { node ->
//this is necessary: need to put the outer tags explicitely
mkp.yieldUnescaped "<li>"
sling.include(node.path)
mkp.yieldUnescaped "</li>"
}
}
h3("Create new")
div(class:"new") {
form(action:"${currentNode.path}/controls/", method:"POST") {
input(type:"text", name:"name", value:"Name")
input(type:"hidden", name:"sling:resourceType", value:"secmanagment/controls")
input(type:"hidden", name:"jcr:primaryType", value:"nt:unstructured")
input(type:"submit", value:"create")
}
}
}
}



While not being too different, those 2 samples (hopefully) show the usage of MarkupBuilders as valid alternative to a templating engine like jsp or gsp.

Kommentare:

111 hat gesagt…
Der Kommentar wurde von einem Blog-Administrator entfernt.
kissouyin hat gesagt…
Der Kommentar wurde von einem Blog-Administrator entfernt.