velocity-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Townson, Chris" <C.Town...@nature.com>
Subject RE: Re: The Guardian website moves to Velocity
Date Fri, 11 May 2007 12:51:36 GMT
> I'm actually quite interested in this sort of thing and I 
> wrote a blog 
> article about it. You might or might not find it interesting. Other 
> people might (or might not) find it interesting as well:
> 
> http://freemarker.blogspot.com/2006/07/designerdeveloper-division-of-labor.html
> 
> There, you see that, I make no bones about what I think regarding 
> Velocity. It definitely seems to me that VTL is lacking certain basic 
> features that you would need to build reusable components. The macro 
> system is just too deficient.
> 

Jonathan,

I would agree with you that macro support in Velocity is not sufficient for constructing what
might be called a "modular" or "component"-based system. As far as I am aware, it was ever
intended for that purpose. Personally, I regard macro functionality as being more akin to
what might be termed "snippets".

[for those who are interested in "modular" or "component"-based templating systems, read on
... ;D If not, you've probably stopped reading already anyway.]

For our usage of Velocity, I recommend against the use of macros for all but the most simple
use cases. I do not do so because of limitations in Velocity macro support but because using
this feature for the creation of reusable "components" would imply a level of scripting which
I would argue is not optimally achieved within a templating language. All this talk of "macros"
is a red herring, IMHO. Hence, we are not utilizing macros at all for the modular system I
referred to in my original e-mail.

A display component is, for all intents and purposes, a domain object (or a facade upon one)
some properties of which one wishes to expose for display purposes and, potentially, to decorate
with additional display-specific properties. Additionally, a display component is an object
the display context of which one requires to be able to detect and subsequently act accordingly
thereupon. Consequently, I would suggest that the required functionality of a "component framework"
extends to the following:

1. Obtaining an instance of a domain object
2. Determining the context in which that instance is being invoked

Neither of these requirements, I would argue, fall within the remit of a template language.
This is why we are building our system in a manner that is entirely decoupled from Velocity.

Why mention it on the Velocity list? Because we _do_ want to render components that this system
is capable of creating instances of. Therefore, we have built a Velocity client (basically,
a Velocity directive ... and we made a tool for the hell of it - because it was so simple
to do). This client obtains a component object instance, discovers the contextual display-related
data (e.g. template name etc that the framework loads on the basis of the request) and renders
it in-situ at the point the directive resides in the template.

At this point one might think "Hey, isn't that a built like a view-layer 'pulling' data and
isn't that A Bad Thing?"

Well, yes and no (to both parts of that question).

What the above enables us to do is to have something like the following:

--- in the main "view" template ---

#component("MyComponent", {"id":$myComponent.id}) ## the webapp is still responsible for pushing
the id of the component you want to display into the view (amongst other data, in all probability)

--- end ---

... but we can have an entirely independent "component template" that makes the most of the
beautiful simplicity of VTL and simply displays the properties of an object (info about which
the template authors can obtain from javadoc)!

--- component template ("MyComponent.vm") ---

<h1>${this.heading}</h1>
<p>${this.text}</p>

--- end ---

Additionally, because we have access to contextual information about where the component is
being displayed, we can (for example) easily get the Velocity client to use different templates
based upon that data (in practice, this happens transparently on the basis of conventions)

However, because we have not written our components as VTL or Freemarker macros, we can easily
go ahead and make alternative clients (e.g. a JSON client ... or even a web services client
using a RESTful or SOAP api ... or even a FreeMarker client! ;D) which re-use the exact same
components.

But doesn't that mean having to create loads of java classes and restart the server (which
would be a pain in the arse)?

Again, yes and no. If a component has to implement complex functionality, then yes: it requires
implementation in Java - but that would be the appropriate place to implement such functionality.

On the other hand, one can simply use a named "dynamic component" to utilize the contextual
data and rendering functionality available by way of the Velocity client in templates; e.g.

--- in the main "view" template ---

#component("DynamicComponent", {"name":"MyDynamicComponent"}) ## this basically making a map
the property names and values for which are determined contextually

--- end ---

template is not quite as simple, but remains far more readable than some horrific macro spaghetti
...

--- component template ("MyDynamicComponent.vm") ---

<h2>${this.get("heading")}</h2>
<p>${this.get("text")}<p>

--- end ---

> Large, complex, modular sites using Velocity, eh? I suppose it's 
> possible. But really, you know, when you can't even #parse a set of 
> commonly used macros in a separate file, and there's no notion of 
> scoping or namespaces whatsoever, so that any variable 
> defined locally 
> in a macro potentially clobbers variables defined elsewhere 
> -- to rely 
> on that kind of tool to build something complex and modular, does not 
> seem like a very good technical decision. The tool simply lacks 
> necessary things for modularity.
> 

It's more than possible: we've already done it even without the formalized support provided
by the "framework" I describe above (which is really just a bit of hackery on top of Spring)
being in place - and we are by no means alone in that (rather simple) achievement.

Nonetheless, I think it would be foolishness to try and assert that Velocity is in some way
"pure and flawless". Proper whitespace handling would be a requirement in my book (and, yes,
I know FreeMarker has this already).

So why didn't we just make a FreeMarker client and use that?
1. Because we were already using Velocity (I know there is a template conversion tool, but
there are other considerations such as familiarity of client-side developers with current
systems, skills investment etc)
2. (And this is the main reason) Because Velocity explicitly does not attempt to be a solution
which bundles everything and the kitchen sink. The clear delineation of responsibility (basically,
taking a context+template and rendering) combined with clear extension points and an elegant
syntax made it ideal for our purposes.

> 
> > 
> > There might be some common ground covered between us and 
> The Guardian here 
>  > which could be fed back into the Velocity project itself, perhaps?
> 
> Well, historically, lobbying Velocity developers for features 
> that you 
> need has not been a very fruitful path. I won't go on further about 
> that, but surely you can perceive that, even bending over 
> backwards to 
> be generous and all, you can't describe this as a very dynamic 
> environment, can you?
> 

From my reasoning above, you may have guessed that I am not lobbying for new features. Far
from it: the restriction to a clearly delineated requirement is a virtue that Velocity possesses.
I would never want it to come bundled with it's own "component framework", for example.

"Fed back into the Velocity project" might imply a couple of things:
1. Us potentially making available our framework code and Velocity client but as an entirely
separate entity (in the same way that Malcolm and the Click project might be thought to "feed
back" into the Velocity project).

2. The possibility of simply "donating" the code such that it might be maintained as a sub-project
were we to decide against maintaining our development as an open source project (which is
not a commitment to be taken on lightly).

Obviously, I cannot speak for The Guardian in any way on this subject and merely mentioned
them in this context in case they were watching ;D

Best wishes,

Chris

********************************************************************************   
DISCLAIMER: This e-mail is confidential and should not be used by anyone who is
not the original intended recipient. If you have received this e-mail in error
please inform the sender and delete it from your mailbox or any other storage
mechanism. Neither Macmillan Publishers Limited nor any of its agents accept
liability for any statements made which are clearly the sender's own and not
expressly made on behalf of Macmillan Publishers Limited or one of its agents.
Please note that neither Macmillan Publishers Limited nor any of its agents
accept any responsibility for viruses that may be contained in this e-mail or
its attachments and it is your responsibility to scan the e-mail and 
attachments (if any). No contracts may be concluded on behalf of Macmillan 
Publishers Limited or its agents by means of e-mail communication. Macmillan 
Publishers Limited Registered in England and Wales with registered number 785998 
Registered Office Brunel Road, Houndmills, Basingstoke RG21 6XS   
********************************************************************************
Mime
View raw message