Guido,

Deinhammer, Guido wrote:
I understand my writing turned out a little lengthy, but if you are
using macros, it should be worth the read...

It definitely is. Thanks for investigating /and providing code/!

The second parameter is a map that is added to the
context under the name "args" - the "macro" can access the parameters
with $args.arg1.

What about wrapping the current VelocityContext in another one that contains the argument map? That would allow you to use your template either through your #call directive or with #parse (because it would remove the need for the "$args." prefix).

It would be an easy fix. Starting with CallDirective.java:120:

    Object oldArgs = context.put(ARGUMENTS_VARIABLE_NAME, args);

Change this to:

      // Wrap the outer context with a new one
      Context subContext = new VelocityContext(context);

      // Copy the arguments into the inner context
      for(Iterator i=args.entrySet().iterator(); i.hasNext(); ) {
          Map.Entry entry = (Map.Entry)i.next();
          subContext.put((String)entry.getKey(), entry.getValue());
      }

I think you can choose to use the wrapped versus outer context however you want... I did not really understand why this was true:

    // the callStack is needed for the ContentDirective - when the content is 
rendered,
    // we have to move one level back in the callStack

... so it's up to you. ;)

Of course, you'd want to use the wrapped context, here:

      template.merge(context, writer);

        template.merge(subContext, writer);

And this line is unnecessary, since subContext will simply fall out of scope:

    context.put(ARGUMENTS_VARIABLE_NAME, oldArgs);

I'm also not sure about the push and pop of template names if you use a wrapped context. I don't know enough about the internals of Velocity to know if they are required or not.

Let me know if you think these are reasonable improvements.

-chris

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to