Re: Nested Java directives - best practice on how to make values available to inner directive?
Daniel Dekany <[email protected]>
| Newsgroups | gmane.comp.web.freemarker.user |
|---|---|
| Message-ID | <[email protected]> |
Thursday, January 31, 2008, 4:51:14 AM, Alistair Israel wrote:
> I've searched the mailing list archives up to a several months back
> but couldn't find anything on this.
>
> What I'm basically trying to do is write a custom "@form" directive in
> Java. Within the @form directive's body, I'd like to have various
> "@input" directives (also written in Java). As to why I would want to
> do this in Java rather than as a regular macro - I want the directives
> to insert Javascript validation code based on annotations on the form
> bean object.
>
> So, conceptually, I'd like to be able to say:
> <@form name="someForm" action="someAction">
> <@input type="text" property="name"/>
> </@form>
>
> I'd like to make the value of @form name ("someForm") available to the
> @input directive (so the @input directive can lookup the name from the
> template model, inspect the class, find annotations and so on and so
> forth.
>
> At first I tried adding a local variable via
> Environment.setLocalVariable() in my directive's execute(). This fails
> with "Not executing macro body".
>
> Delving through the code, it's apparent that while a custom macro
> directive has currentMacroContext (that lets us define/access local
> variables through the ".locals" special variable), a custom Java
> directive doesn't. Why is that so?
I'm not too familiar with the source-code, but I suppose because Java
language already has its own system of variables (like fields, local
variables on the stack, TLS, etc). Anyway, what you are looking for is
called "parent-child communication" or "parent-children communication"
on this list. But this feature was only added in 2.4, which is
unreleased and unstable. Also I don't think even there this was solved
when the "parent" is a TemplateDirectiveModel (or
TemplateTransformModel) call.
To fellow FM developers:
- Given that 2.4 will not be released in the foreseeable future, and
even then it will not be 100% BC, parent-children communication
definitely should be backported to 2.3.x. This is again a very basic
feature for a template language, shame that it isn't there for
years. (Reminds me to the history of #nested...) Would backporting
be difficult?
- Can TemplateDirectiveModel and TempateTransformModel calls
participate as parents in the current trunk? (And as children for
that mater?) I don't think so... of course, they should be able to.
Java and FTL are just to languages to implement custom directives.
> So, I was able to make it work by using a global variable instead
> (Environment.setGlobalVariable()). The only thing that bothers me is
> that it really doesn't need to be a global variable - the scope of the
> value of the current form name is just that: the current form. I could
> conceptually overwrite or define a global variable that other
> templates depend upon for other purposes.
As far as I know that's still the best workaround you can do right
now.
> [ Aside: perhaps if there was some way to use namespaces to
> distinguish my directives (as well as any 'local' variables they need)
> it wouldn't bother me as much. However, using
> Configuration.setSharedVariable (via Spring's FreeMarkerConfigurer)
> only lets me provide a simple string name - not sure if any prefixes
> (e.g., "my.form") will be interpreted as a namespace.
They won't be (unless the Spring guys did some big trick...), since a
shared variable is always a top-level variable, for technical reasons.
Of course, the value of the shared variable can be a map or JavaBean
or something other structural, so if "my" is the name of the shared
variable, and it's value has a "form" subvariable (JavaBean property
or whatever), then you have that my.form.
> This, in fact, was a separate question I meant to ask the list. ]
>
> How would the members of the list suggest I do this - make a value
> local to my parent directive available to nested directives - short of
> explicitly passing them?
I say, use globals for now... Which can be even more irritating when
you have directives that can be nested into the same kind of directive
(like: <@ul bullet="box.gif">...<@ul bullet="arrow.gif">...</@ul>...</@ul>)
> - Alistair A. Israel
--
Best regards,
Daniel Dekany
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/