Velocity Engine Extension (Was: [Helma-dev] Template Engines)

Juerg Lehni juerg at scratchdisk.com
Thu Nov 24 14:50:41 CET 2005


Yes, it's an extension.

And while I was at it, I implemented Freemarker as well.

Freemarker seems the better of the two, I'm using this now for a new  
project of mine.

I'm not sure Helma should provide it's own mechanism for templates at  
all. These are both pretty healthy projects that will grow and are  
maintained.

The integration feels rather natural.

I will test a bit more and upload both together later on.

One thing I noticed:

It would help a lot of ResponseTrans could be made a subclass of  
java.io.Writer

As far as I can tell there wouldn't be any complications, and it  
would make integration of such 3rd party projects easier.

Would you accept a patch for this? Otherwise I just continue my  
java.io.Writer wrapper...

And a cosmetical question:

What do you think the renderTemplate functions should to be called?  
renderVelocity / renderFreemarker? or just renderTemplate, and then  
one can't mix template engines per project (I think that make sense  
and would force people to not do it...)

Jürg

Am 24.11.2005 um 11:47 schrieb Hannes Wallnoefer:

> Sounds wonderful!
>
> If this is a Helma extension (as I understand it), it should probably
> go int the extensions directory of the Helma CVS.
>
> http://adele.helma.org/source/viewcvs.cgi/extensions/?cvsroot=hop
>
> Is this ok with you? Let me know if you need any help with checking  
> in.
>
> hannes
>
> 2005/11/23, Juerg Lehni <juerg at scratchdisk.com>:
>> I finished the code for this now.
>>
>> renderTemplate is now automatically added to the HopObject prototype
>> when an application activates the velocityEngine. The global velocity
>> variable is gone.
>>
>> renderTemplate could also be named differently...
>>
>> The only necessary change to Helma was to make
>> helma.framework.core.Prototype.getResources() public.
>>
>> I'm pretty happy with this, the added flexibility for templates
>> simplifies quite a few things. And it can coexist nicesly with
>> existing templates, as the velocity templates have the extension .vm
>>
>> Access to variables and functions is possible too.
>>
>> I'm not sure if all functions of "this" should be exposed though.
>> E.g. remove() is pretty dangerous to be called from the template.
>> Maybe I'll define a suffix similar to _macro which is added to the
>> function name before calling, in order to add some security measures.
>>
>> I noticed that it's about 1.5 - 2.5 slower than Helma's renderSkin. I
>> guess this is because it is more complex and obviously less optimized
>> than renderSkin.
>>
>> So if I could upload this to CVS somewhere I'd be happy to make this
>> available to everyone.
>>
>> Jürg
>>
>> Am 23.11.2005 um 17:09 schrieb Juerg Lehni:
>>
>>> Thanks, Hannes.
>>>
>>> I had to make the helma.framework.core.Prototype.getResources()
>>> function public.
>>>
>>> My velocity extension is working quite well now.
>>>
>>> It is caching templates and only parsing them when they changed, so
>>> performances should be high.
>>>
>>> I created a HelmaExtension out of it, so if a app defines
>>> velocityEngine = true in app.properties, it will have a global
>>> variable called velocity, through which it can access the templates.
>>>
>>> HopObjects then can define a render function like this:
>>>
>>> function renderTemplate(name, param) {
>>>       velocity.renderTemplate(this, name, param);
>>> }
>>>
>>> and from then on, the velocity extension can be used just like
>>> renderSkin.
>>>
>>> I'd like to submit this for others ot use as well.
>>>
>>> Would it make sense to create a CVS repository for it?
>>>
>>> Jürg
>>>
>>> Am 23.11.2005 um 15:43 schrieb Hannes Wallnoefer:
>>>
>>>> I can't respond in length because I'm on the run, but the right  
>>>> place
>>>> to implement a per-HopObject getResource would probably be
>>>> helma.framework.core.Prototype. You have all your repositories and
>>>> resources there. Then you'd need to implement a scripting stub in
>>>> helma.scripting.rhino.HopObject, which shouldn't be too dificult.
>>>>
>>>> hope that helps, more later.
>>>> hannes
>>>>
>>>> 2005/11/23, Juerg Lehni <juerg at scratchdisk.com>:
>>>>> I started embeding Velocity in Helma now and roughly it's already
>>>>> working.
>>>>>
>>>>> Accessing the request, response and session objects from velocity
>>>>> templates is possible, and looping through passed arrays as well.
>>>>>
>>>>> But I'm struggling with how to nicely integrate it in Helma.
>>>>>
>>>>> My main problem is how to find the template resources in the
>>>>> repositories in an easy way. The default files
>>>>> (.skin, .js, .hac, .type) are cached in Prototype. For additional
>>>>> file-types, I need to iterate through all the repositories and
>>>>> subrepositories of the application.
>>>>>
>>>>> I wonder if there could be a function getResource() in HopObject
>>>>> that
>>>>> would return the given resource in the prototype folder,  
>>>>> regardless
>>>>> of the extension. This would offer an easy hook for integrating  
>>>>> the
>>>>> template engine.
>>>>>
>>>>> Or maybe it should be a level higher, in the skin manager? Like
>>>>> this,
>>>>> even external skin folders would be supported. But as Skins are
>>>>> stored in parsed Skin objects, I would then need to access the
>>>>> skin's
>>>>> getSource() property to get the raw source and create a tempalte
>>>>> from
>>>>> that...
>>>>>
>>>>> Any pointers for this would be very appreciated, as I'm a bit
>>>>> blocked
>>>>> right now.
>>>>>
>>>>> Jürg
>>>>>
>>>>> Am 23.11.2005 um 11:53 schrieb Juerg Lehni:
>>>>>
>>>>>>
>>>>>> Am 23.11.2005 um 11:31 schrieb Hannes Wallnoefer:
>>>>>>
>>>>>>> 2005/11/23, Juerg Lehni <juerg at scratchdisk.com>:
>>>>>>>> Another advantage of Rails seems to be the more flexible  
>>>>>>>> template
>>>>>>>> engine that allows loops and if / else constructs in the
>>>>>>>> templates
>>>>>>>> (skins).
>>>>>>>
>>>>>>> Well, what Rails does is basically the same as Helma's
>>>>>>> old .hsp, i.e.
>>>>>>> embedding Ruby code in templates. I really thought it was a good
>>>>>>> thing
>>>>>>> when we went over that. The critical question in this regard
>>>>>>> will be
>>>>>>> how easy we can make it to implement macros in Helma 2.0.
>>>>>>
>>>>>> I agree that this is not a good idea. For Rails there's liquid  
>>>>>> now,
>>>>>> which avoids this problem and offers programming constructs:
>>>>>>
>>>>>> http://home.leetsoft.com/liquid
>>>>>>
>>>>>>>
>>>>>>>> I was wondering how this will be adressed in Helma 2.0?  
>>>>>>>> There are
>>>>>>>> powerfull Java libraries around for this, e.g. Velocity  
>>>>>>>> ( http://
>>>>>>>> jakarta.apache.org/velocity/ ) and FreeMaker ( http://
>>>>>>>> freemarker.sourceforge.net/ ).
>>>>>>>>
>>>>>>>> Hannes, are you considering embeding one of those, or will  
>>>>>>>> Helma
>>>>>>>> feature its own engine, that might implement the programming
>>>>>>>> constructs in a way that is closer to the JavaScript syntax?
>>>>>>>
>>>>>>> I think it should be possible to use a third party templating
>>>>>>> engine
>>>>>>> with Helma. There will be a proprietary implementation, though.
>>>>>>>
>>>>>>> One current idea, pretty offhand, is to use custom markup  
>>>>>>> tags or
>>>>>>> attributes:
>>>>>>>
>>>>>>> <div h:foreach="storylist">
>>>>>>>   <h3 h:content="story.title">Title</h3>
>>>>>>>   ...
>>>>>>> </div>
>>>>>>>
>>>>>>> Explanation: If the h:foreach attribute evaluates to an  
>>>>>>> array, the
>>>>>>> inner skin is rendered on each array element. If statements
>>>>>>> could be
>>>>>>> build in a similar fashion:
>>>>>>>
>>>>>>> <div h:if="story">
>>>>>>>     <h3 h:content="story.title">Title</h3>
>>>>>>>   ...
>>>>>>> </div>
>>>>>>>
>>>>>>> As I said, I'm writing this offhand, we may already have done  
>>>>>>> this
>>>>>>> better somewhere on the mailing list.
>>>>>>
>>>>>> Interesting. But how would I add logic that is not bound to a  
>>>>>> html
>>>>>> tag? I also wonder if it wouldn't become a bit hard to actually
>>>>>> spot the logic parts in a skin if they're all nested inside tags
>>>>>> (without using the editor's search function and searching for
>>>>>> "h:").
>>>>>>
>>>>>> In Velocity, it looks like this:
>>>>>>
>>>>>> #foreach( $mud in $mudsOnSpecial )
>>>>>>    #if ( $customer.hasPurchased($mud) )
>>>>>>       <tr>
>>>>>>         <td>
>>>>>>           $flogger.getPromo( $mud )
>>>>>>         </td>
>>>>>>       </tr>
>>>>>>    #end
>>>>>> #end
>>>>>>
>>>>>> And this is a Liquid template:
>>>>>>
>>>>>> {% if user.age > 18 %}
>>>>>>    <a href="...">pron here</a>
>>>>>> {% else %}
>>>>>>    <a href="http://www.disneyland.com/">disney</a>
>>>>>> {% endif %}
>>>>>>
>>>>>> {% for item in array %}
>>>>>>    {{ item }}
>>>>>>  {% endfor %}
>>>>>>
>>>>>> This seems to be somehow easier to read.
>>>>>>
>>>>>>>> And is this something I could help with for 2.0?
>>>>>>>
>>>>>>> Yes, of course you can. Keep having good ideas, try out things,
>>>>>>> start
>>>>>>> using dev.helma.org wiki :-)
>>>>>>
>>>>>> Ok! I'll play around a little and see what I come up with.
>>>>>>
>>>>>> Jürg
>>>>>>
>>>>>>>
>>>>>>> hannes
>>>>>>>
>>>>>>>> Jürg_______________________________________________
>>>>>>>> Helma-dev mailing list
>>>>>>>> Helma-dev at helma.org
>>>>>>>> http://helma.org/mailman/listinfo/helma-dev
>>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> Helma-dev mailing list
>>>>>>> Helma-dev at helma.org
>>>>>>> http://helma.org/mailman/listinfo/helma-dev
>>>>>>
>>>>>> _______________________________________________
>>>>>> Helma-dev mailing list
>>>>>> Helma-dev at helma.org
>>>>>> http://helma.org/mailman/listinfo/helma-dev
>>>>>
>>>>> _______________________________________________
>>>>> Helma-dev mailing list
>>>>> Helma-dev at helma.org
>>>>> http://helma.org/mailman/listinfo/helma-dev
>>>>>
>>>> _______________________________________________
>>>> Helma-dev mailing list
>>>> Helma-dev at helma.org
>>>> http://helma.org/mailman/listinfo/helma-dev
>>>
>>> _______________________________________________
>>> Helma-dev mailing list
>>> Helma-dev at helma.org
>>> http://helma.org/mailman/listinfo/helma-dev
>>
>> _______________________________________________
>> Helma-dev mailing list
>> Helma-dev at helma.org
>> http://helma.org/mailman/listinfo/helma-dev
>>
> _______________________________________________
> Helma-dev mailing list
> Helma-dev at helma.org
> http://helma.org/mailman/listinfo/helma-dev



More information about the Helma-dev mailing list