You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@sling.apache.org by "jmilkiewicz@gmail.com" <jm...@gmail.com> on 2011/01/03 22:54:52 UTC

freemarker

.Hi

I am evaluating CQ5/Sling and have a 2 questions of freemarker support. If
any of these questions should be addressed to other mailing list please
don't hesitate to point it.

In a sling  there is a freemarker scripting engine that binds some objects
(like current node) to freemarker model map and then executes ftl template
feeding it with the model.
That's fine but since freemarker support is based on scripting engine - all
freemarker request are routed through single class i.e.
FreemarkerScriptEngine,  I find this approach a little bit limited.

I am much more into old school freemarker usage:  create sling servlet that
handles specific request URL (like http://foo.bar/app/productList),  let
that servlet build model, load freemarker template and send freemarker
template processing result to outputstream.
In code it looks like this:
[code]
class MyProductSlingServlet extends  SlingSafeMethodsServlet{
   public void doGet(SlingHttpServletRequest request,
SlingHttpServletResponse response){
    Map model = buildSpecificModel(request);
    Template freemarkerTemplate = getTemplate(request);
    freemarkerTemplate.process(model, response.getWriter());
   }
}
[/code]

To make it work i had to deploy osgified freemarker into Felix.

Employing this approach i can write servlet that can build specific model
for the specific request.  So building model and choosing appropriate ftl
file  is nicely encapsulated in a servlet created to handle given request.
It is a major difference to that how it works in sling freemarker scripting
since the latter only binds "current node" to freemarker map  (asfaik this
behavior can be extended by using mechanism to allow bundles to contribute
script binding values) but indeed I can see no dedicated building model per
request mechanism.

Any comments from more experienced CQ5/Sling users ?


The other thing i bumped into is the fact that freemarker scripting support
in sling is an OSGI bundle (org.apache.sling.scripting.freemarker) with
freemarker embedded.  Why is it done like that ?
Isn't it more natural and correct to have that bundle contains only it's own
classes and then specify that it imports freemarker.template package.It
would require installing of 2 bundles:
osgified freemarker and freemarker scripting support bundle but the final
solution would be more OSGI friendly.
As a matter of face today i did some sample coding and wanted to extend the
code presented above by putting current node object into model map. Looking
at
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/freemarker/src/main/java/org/apache/sling/scripting/freemarker/FreemarkerScriptEngine.java?view=markupit
seemed quite simple:
[code]
Resource resource = request.getResource();
Node n = resource.adaptTo(Node.class);
model.put("currentNode", new NodeModel(n));
[/code]

Everything seemed to work fine and i was able to reach currentNode variable
and its properties from my ftl file. The problem was that instead of getting
string values of properties i did get strings like:
org.apache.sling.scripting.freemarker.wrapper.PropertyModel@1fsa2 . For 100
% it wasn't value of the property i referenced to and it looked to me like
the result of toString() call on
org.apache.sling.scripting.freemarker.wrapper.PropertyModel instance.

After a short investigation i found out that  the problem was caused by 2
version of freemarker in the system: the one i installed myself - to use
freemarker in my sling servlet,  and the second one from freemarker
scripting support.
Since freemarker processing is triggered by my sling servlet all template
building and processing is done in the context of (my own installed)
osgified version of freemarker. If NodeModel (or any of its child) is to be
rendered it returns instances  that reference/implement freemarker classes.
Unfortunately these classes were loaded from freemarker scripting support
bundle, hence by a different classloader from the one that processes ftl
template so the property values couldn't be correctly rendered.
The solution was straightforward: just remove embedded freemarker from
freemarker scripting support bundle and let the bundle import (osgified)
freemarker.
I believe it is a bug that freemarker is embedded into freemarker scripting
support bundle and it should be removed asap.


regards miluch