On Wed, Feb 20, 2008 at 2:18 PM, Geir Magnusson Jr. <[EMAIL PROTECTED]> wrote: > There was something really sucky about it, which is why I didn't move > it forward. I forget why it was bad...
Hmm. Well, that's a good reason to wait for some good test code for it before we consider promotion... > geir Btw, Geir, did you ever find that old code you had for escaping quotes in strings? (https://issues.apache.org/jira/browse/VELOCITY-555) If not, do you remember the gist of how you implemented it? I'm interested in taking a stab at this before pushing an Engine 1.6 release, but i'm not sure how to do it. > > > 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 > > <[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] > > > > > --------------------------------------------------------------------- > 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]