Here I want to provide a set of examples for context chaining.
Comments to other issues in this thread are in a separate post.
A. Without
1. instantiate VelocityContext
2. populate it
3. render template
This has been the form before chaining was possible. It has
the (small) drawback that the objects and tools placed into
it are modifyable (specially problematic within VMs/recursion
and #parsed files).
B. Typical inmutable context setup:
1. instantiate an intial VelocityContext
2. populate it with global tools/objects (must be thread safe!)
2a. optionally chain it to protect objects (make it inmutable)
3. upon each request: clone it
4. populate it with other tools/objects
6. remove/mask-out tools/objects depending on security issues
5. chain it with another VelocityContext to protect objects
7. render template
C. During macro processing
8. Add another chained context:
a) In the VM setup: add a chained context containing only
the passed VM parameters. Any #set is then local and does
not affect the parent context. This has an performance
impact.
Geir mentioned something on making the passed parameters
the only ones that may affect the parent context... I can't
figure out a sensible/reliable form of doing this.
b) Via #local($vars...)...#end (This is my preffered way.)
Here only the $vars parameters to the PD are local and so
dropped after the end. All other #sets affect the parent
context.
A local block is added only if the VM requires local vars
and can be left away for performance reasons - up to the
designer.
This requires a LocalContext implementation, but does not
affect any other Vel feature!
This would also safely enable Geir's recursion...
c) Something Geir/Jose are talking about... without chaining?
D. During normal template processing
Same as C.8.b) above, thus allowing local variables independent
of any current context definitions.
This is *very* useful whithin #parsed files and safely avoids
any conflicts (e.g. to create safe reusable template and macro
libraries).
This is also useful to use variables that do not remain and
pollute the context after their use has completed. They disapear
after the #end! This is similar to a for(int i;;){int j;...}
where i and j are local.
Any use I missed?
:) Christoph