Re: partial evaluation / removing directives

Nathan Bubna <[email protected]>
Newsgroups gmane.comp.jakarta.velocity.user
Message-ID <CAFyaDjFuT4zrXOR4VDzeDKEwyvgv6gw4qOfOQ0Vjh3g5hqqMsw@mail.gmail.com>
On Thu, Jul 12, 2012 at 2:27 PM, Pete <[email protected]> wrote:
> Hi all,
> I'm working with some velocity files where I want to partially evaluate
> them, such that the only things actually evaluated are #parse (includes of
> other velocity templates in the same directory) and  $references to a
> resourceBundle variable passed in the context map.  In essence, all this is
> doing is combining a number of velocity files into one master velocity
> file, and localizing any resource bundle references to a given locale. All
> the main velocity directives in the velocity file(s) should be left
> unevaluated-   #set, #ifelse, #foreach etc. This way, the result could be
> redistributed and modified specific to a particular locale, with just one
> file instead of n based on the #parse structure.

interesting challenge!  glad i don't have to do it though. :)

> Up till now, I've been doing this in a somewhat roundabout way:
> 1. setting strict escape property to true
> 2. pre-processing the velocity templates by regexp replacing all instances
> of #if / #else/ #elseif/ #end / #foreach / #define / #break / #stop  #set /
> #evaluate with  \\#{$1}
> This adds a an escape character before each of these directives, and I can
> then call mergeTemplate on the result.  It works OK, sometimes, but I still
> run into some parsing issues now and again (eg not a robust solution). It
> also seems kind of heavy handed to have to preprocess these files using a
> regular expression and saving them before velocity gets a handle on them.
> It would even be a bit better if I could do this by reading them in and
> doing the rgexp in-memory rather than on the saved files, then using
> evaluate instead of mergeTemplate. But I assume that would cause problems
> for the #parse directives.

Why would evaluate cause problems for #parse??  If the engine is
configured the same, the #parse should work the same whether you enter
via file or string.

> I know velocity added a removeDirective() method in 1.6.2 which seems like
> it should be perfect for me - I could simply rip out all the directives but
> #parse.  However, I tried the and it seems that it only works for certain
> directives, eg  #foreach, #include, etc.  More basic directives like #if
> and #elseif are not in the list of runtimedirectives, or even represented
> as Directive objects, so removing them doesn't work.

Yeah, they are deep in the parser.  Their structure doesn't work as a
normal directive.

> Any suggestions on the best way to proceed with this? Would it be easy to
> change a few velocity files locally, recompile and get this behavior? Or is
> it sufficiently complex removing all these more basic directives that I'm
> better off continuing to try some kind of  preprocessing/ escaping?

You would have to redesign Velocity's parsing deeply.  A major
overhaul.  You're best off preprocessing.   Have you considered using
a different template engine to do the first part (the parse and
resourceBundle resolution)?  Might be overkill, but might be easier,
so long as the syntax has no overlap with VTL.

> thanks,
> Pete
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.