Re: Extensions to allow introspection of Freemarker template

Daniel Dekany <[email protected]> Wed, 28 May 2014 21:54:42 +0200
Newsgroups gmane.comp.web.freemarker.devel
Message-ID <[email protected]>
Tuesday, May 27, 2014, 3:58:05 PM, Wong, Christopher wrote:

> I work with user-submitted templates, and would like Freemarker
> support some form of introspection of a template. For example, I
> might want to know what identifiers the template will request from
> the model.

Note that in general it's impossible to tell if a variable refers to a
data-model variable, or a something more local. #assign, #global, and
even #local shadow the data-model only after it was executed. (That's
BTW why I want to deprecate them in the far future... the sabotage
static analysis.)

> Freemarker already has something very close to this: the
> public method Template.getRootTreeNode exposes a DOM-like structure
> the end user. Unfortunately, the TemplateElement classes that comes
> back are mostly not visible to the public.
>  
> Since I'd rather not fork an internal copy of Freemarker, I'd like
> to explore the possibility of contributing changes to the Freemarker
> project to enable template introspection.

You can create classes that are inside the freemarker.core package in
your own project, and then those classes can access all those AST
nodes. No need for forking for that. Of course, the problem with that
approach is that there's no backward compatibility guarantee for the
internal classes. But then, doing this hack is still more maintainable
than a fork.

> I want to see if there's an approach that the maintainers will find
> acceptable.
>  
> 1) The easiest way to accomplish this is to make the
> TemplateElement hierarchy public and add public getters to these
> classes. On the other hand, this might expose more than you'd like.

Yes, that's a problem... Those internal classes are a bit of a mess
too.

> 2) You have implemented similar functionality by having this class
> implement the TreeNode interface to expose this tree as a Swing
> component. Perhaps a separate interface hierarchy will provide acceptable decoupling?

So, I guess we should define interfaces that show the contents of a
template in a future proof (an thus high level) and intuitive way. If
the currently used AST nodes can be changed to implement those
interfaces, that's a plus of course, but the point is exactly that
they don't have to able to do so. At least for the first iteration,
I'm thinking about something really lightweight and "dynamic", where
you don't have a sub-interface for each kind of AST nodes (there's a
ton of them, and more can come anytime), instead, you can just get
what kind of node is that (built-in directive, operator, etc.) and a
string that gives its name ("include", "+", etc.) and it's
parameters/operands. This thing could be in another project, let's
say, freemarker-introspection. This kind of feature would be useful
for IDE-s too, for outline views and so on. Some of the classes in
freemarker-introspection will have to be inside freemarker.core, but
if it turns out to be something good, then it will be maintained
together with FreeMarker, so then you have backward compatibility
guarantee after all.

-- 
Thanks,
 Daniel Dekany


------------------------------------------------------------------------------
Time is money. Stop wasting it! Get your web API in 5 minutes.
www.restlet.com/download
http://p.sf.net/sfu/restlet