velocity-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Geir Magnusson Jr." <g...@pobox.com>
Subject Re: Call a velocity macro
Date Wed, 20 Feb 2008 22:18:36 GMT
There was something really sucky about it, which is why I didn't move  
it forward.  I forget why it was bad...

geir

On Feb 20, 2008, at 5:16 PM, Nathan Bubna wrote:

> 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  
> <adrian.tarau@gmail.com> 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?
>>
>>
>>
>> apache@recks.org 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:adrian.tarau@gmail.com] 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:adrian.tarau@gmail.com] 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: dev-unsubscribe@velocity.apache.org
>>>>>> For additional commands, e-mail: dev-help@velocity.apache.org
>>>>>>
>>>>>>
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: dev-unsubscribe@velocity.apache.org
>>>>> For additional commands, e-mail: dev-help@velocity.apache.org
>>>>>
>>>>>
>>>>
>>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@velocity.apache.org
>>> For additional commands, e-mail: dev-help@velocity.apache.org
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@velocity.apache.org
>> For additional commands, e-mail: dev-help@velocity.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@velocity.apache.org
> For additional commands, e-mail: dev-help@velocity.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@velocity.apache.org
For additional commands, e-mail: dev-help@velocity.apache.org


Mime
View raw message