I'm pretty sure #local is still just in Geir's whiteboard section.  No
one has ever gotten it promoted out of there.  I've never been opposed
to it, but i've also never been interested in putting the work needed
into it (tests, docs, etc).

http://svn.apache.org/repos/asf/velocity/engine/trunk/whiteboard/geir/Local.java

On Wed, Feb 20, 2008 at 2:09 PM, Adrian Tarau <[EMAIL PROTECTED]> wrote:
> Thanks,
>
>  I think I will implement a different directive, based on #parse but
>  passing the parameters & having all the variables local to the "function".
>  I'm not aware of any directive called #local. What do you mean?
>
>
>
>  [EMAIL PROTECTED] wrote:
>  > Hi Adrian,
>  >
>  > in a similar scenario I use the #parse directive and placed the code
>  > snippets (aka. macros) into a *.vtl file each. Something like:
>  >
>  > #set( $component = ... )
>  > #set( $type = $component.type )
>  > #parse("renderComponent${type}.vtl" )
>  >
>  > This has the advantage, that these rendering Templates parsed once and
>  > cached.
>  >
>  > The downside is that the parameter passing is implicit (here
>  > $component is the input parameter for the parsed template) and that
>  > these parsed templates must be careful not to overwrite existing
>  > variables. For this I used a different namespace (postfixed variables
>  > with "_"), but you can also use the new #local directive to avoid
>  > conflicts.
>  >
>  > Cheers,
>  > Christoph
>  >
>  > Adrian Tarau wrote:
>  >> I've always imagined a macro as a function, but as the name says, the
>  >> macro body is expanded at parsing time in the current template. This
>  >> has the advantage to have the template tree in memory and the
>  >> rendering speed is the fastest possible.
>  >>
>  >> What I need is more like calling a template as a function(which
>  >> behave like a function) in the context of the current execution
>  >> context(same context, same writer) without too much overhead.
>  >>
>  >> I will try to implement something like that and I will publish the
>  >> result, maybe it will be useful for somebody else.
>  >>
>  >> Thanks.
>  >>
>  >> Massip, Etienne wrote:
>  >>> A dynamic call of a parameter-given name is a minimal parsing, but
>  >>> still is, preventing any kind of "compile-time linkage" from being
>  >>> done.
>  >>>
>  >>> The "expression" seems to be known only at template-parsing-time,
>  >>> isn't it ?
>  >>>
>  >>> I think
>  >>>
>  >>> #call('render'+$component.type $component)
>  >>>
>  >>> makes very little difference with
>  >>>
>  >>> #evaluate('#render' + $component.type + '($component)')
>  >>>
>  >>> If the evaluate directive really performs poorly, then maybe it
>  >>> should be a good idea to speed it up other than create a new and
>  >>> specialized one ?
>  >>>
>  >>> -----Message d'origine-----
>  >>> De : Adrian Tarau [mailto:[EMAIL PROTECTED] Envoyé : mardi 19
>  >>> février 2008 16:14
>  >>> À : Velocity Developers List
>  >>> Objet : Re: Call a velocity macro
>  >>>
>  >>> Velocity.evaluate or Velocity.invokeVelocimacro(which calls
>  >>> evaluate) doesn't provide support to pass objects as parameters and
>  >>> is not suitable to be called from a template.
>  >>>
>  >>> The new directive #evaluate is actually Velocity.evaluate.  It is
>  >>> still an evaluate, which means expression parsing. I would like to
>  >>> avoid that. If you will call "call/invoke" directive too often I
>  >>> think it will perform badly, due the fact that a parsing step is
>  >>> performed.
>  >>>
>  >>> In this case, a call to a velocity macro, we don't need the parsing
>  >>> step. We know the "expression", and what we need is to prepare the
>  >>> node without parsing.I don't know much about the velocity internals,
>  >>> but I presume it should be possible.
>  >>> And I think such a directive should be part of the core, I mean it
>  >>> will be easy to implement a "switch"(is what I need actually) based
>  >>> on some variable. Like in my case :
>  >>>
>  >>> #macro(renderLabel $component)
>  >>> ....
>  >>> #end
>  >>>
>  >>> #macro(renderTextField $component)
>  >>> ....
>  >>> #end
>  >>>
>  >>> #macro(renderRadioButton $component)
>  >>> ....
>  >>> #end
>  >>>
>  >>> .....
>  >>>
>  >>> #call('render'+$component.type $component)
>  >>>
>  >>> where 'type' is 'label', 'text-field', 'radio-button'(of course
>  >>> there is a normalization of the type value, first character upper
>  >>> case, '-' makes the next character uppercase, etc).
>  >>>
>  >>> Instead of lots of tests with #if, it will be better(and faster) to
>  >>> have this 'switch'.At least it looks better, the template is cleaner
>  >>> and it is (it will be)also faster.
>  >>>
>  >>> Thanks.
>  >>>
>  >>>     /Reader reader = *new* BufferedReader(*new*
>  >>> StringReader(sourceText));
>  >>>         String templateName = context.getCurrentTemplateName();
>  >>>         SimpleNode nodeTree = *null*;
>  >>>
>  >>>         *try*
>  >>>         {
>  >>>             *nodeTree* = rsvc.parse(reader, templateName);
>  >>>         }
>  >>>         *catch* (ParseException pex)
>  >>>         {
>  >>>             //// use the line/column from the template
>  >>>             Info info = *new* Info( templateName, node.getLine(),
>  >>> node.getColumn() );
>  >>>             *throw*  *new* ParseErrorException( pex.getMessage(),
>  >>> info );
>  >>>         }
>  >>>         *catch* (TemplateInitException pex)
>  >>>         {
>  >>>             Info info = *new* Info( templateName, node.getLine(),
>  >>> node.getColumn() );
>  >>>             *throw*  *new* ParseErrorException( pex.getMessage(),
>  >>> info );
>  >>>         }/
>  >>>
>  >>>
>  >>>
>  >>> Massip, Etienne wrote:
>  >>>
>  >>>> Hello
>  >>>>
>  >>>> Take a look at the actual RenderTool
>  >>>> (http://velocity.apache.org/tools/releases/1.4/generic/RenderTool.html).
>  >>>>
>  >>>>
>  >>>> Or at the new evaluate directive, although still in developement
>  >>>> 
> (http://velocity.apache.org/engine/devel/vtl-reference-guide.html#aevaluate_-_dynamically_evaluates_a_string_or_reference).
>  >>>>
>  >>>>
>  >>>> Etienne
>  >>>>
>  >>>> -----Message d'origine-----
>  >>>> De : Adrian Tarau [mailto:[EMAIL PROTECTED] Envoyé : mardi 19
>  >>>> février 2008 07:29 À : dev@velocity.apache.org Objet : Call a
>  >>>> velocity macro
>  >>>>
>  >>>> Hello,
>  >>>>
>  >>>>
>  >>>>
>  >>>> I have the following problem : I would like to call a macro but the
>  >>>> macro name must be a variable.
>  >>>>
>  >>>>
>  >>>>
>  >>>> Ex: instead of #renderLabel($component) to have #call("renderLabel"
>  >>>> $component) - of course "renderLabel" can be any (existing) macro
>  >>>> name.
>  >>>>
>  >>>>
>  >>>>
>  >>>> I started to create a directive #call, but of course the render
>  >>>> method fails because the nodeTree is not initialized. nodeTree is
>  >>>> initialized during parsing like this
>  >>>>
>  >>>>
>  >>>>
>  >>>> public class ASTDirective extends SimpleNode {
>  >>>>
>  >>>>
>  >>>>
>  >>>> ...
>  >>>>
>  >>>>            directive = rsvc.getVelocimacro( directiveName,
>  >>>> context.getCurrentTemplateName());
>  >>>>
>  >>>>
>  >>>>
>  >>>>             try
>  >>>>
>  >>>>             {
>  >>>>
>  >>>>                 directive.init( rsvc, context, this );
>  >>>>
>  >>>>             }
>  >>>>
>  >>>>
>  >>>>
>  >>>> ..
>  >>>>
>  >>>> {
>  >>>>
>  >>>>
>  >>>>
>  >>>>
>  >>>>
>  >>>> Any thoughts? I think such a directive is very useful, I don't know
>  >>>> why is not part of the library.
>  >>>>
>  >>>> Thanks.
>  >>>>
>  >>>>
>  >>>>
>  >>>> CallDirective source code :
>  >>>>
>  >>>>
>  >>>> public class CallDirective extends Directive {
>  >>>>
>  >>>>
>  >>>>
>  >>>>     public String getName() {
>  >>>>
>  >>>>         return "call";
>  >>>>
>  >>>>     }
>  >>>>
>  >>>>
>  >>>>
>  >>>>     public int getType() {
>  >>>>
>  >>>>         return LINE;
>  >>>>
>  >>>>     }
>  >>>>
>  >>>>
>  >>>>
>  >>>>     public boolean render(InternalContextAdapter context, Writer
>  >>>> writer, Node node) throws IOException, ResourceNotFoundException,
>  >>>> ParseErrorException, MethodInvocationException {
>  >>>>
>  >>>>         if (node.jjtGetNumChildren() < 1) {
>  >>>>
>  >>>>             rsvc.error("#" + getName() + " : invalid number of
>  >>>> parameters, must be at least the macro name and 0..N parameters");
>  >>>>
>  >>>>             return false;
>  >>>>
>  >>>>         }
>  >>>>
>  >>>>         String macroName = (String)
>  >>>> node.jjtGetChild(0).value(context);
>  >>>>
>  >>>>         VelocimacroProxy velocimacro = (VelocimacroProxy)
>  >>>> rsvc.getVelocimacro(macroName, context.getCurrentTemplateName());
>  >>>>
>  >>>>         if (velocimacro == null) {
>  >>>>
>  >>>>             rsvc.error("A macro with name '" + macroName + " in
>  >>>> context '" +
>  >>>> context.getCurrentTemplateName() + "' doesn't exists");
>  >>>>
>  >>>>             return false;
>  >>>>
>  >>>>         }
>  >>>>
>  >>>>         return velocimacro.render(context, writer, node);
>  >>>>
>  >>>>     }
>  >>>>
>  >>>> }
>  >>>>
>  >>>>
>  >>>> ---------------------------------------------------------------------
>  >>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
>  >>>> For additional commands, e-mail: [EMAIL PROTECTED]
>  >>>>
>  >>>>
>  >>>
>  >>> ---------------------------------------------------------------------
>  >>> To unsubscribe, e-mail: [EMAIL PROTECTED]
>  >>> For additional commands, e-mail: [EMAIL PROTECTED]
>  >>>
>  >>>
>  >>
>  >>
>  >
>  > ---------------------------------------------------------------------
>  > To unsubscribe, e-mail: [EMAIL PROTECTED]
>  > For additional commands, e-mail: [EMAIL PROTECTED]
>  >
>
>
>  ---------------------------------------------------------------------
>  To unsubscribe, e-mail: [EMAIL PROTECTED]
>  For additional commands, e-mail: [EMAIL PROTECTED]
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to