Tuesday, August 29, 2017, 8:48:34 PM, Woonsan Ko wrote: > On Tue, Aug 29, 2017 at 10:40 AM, Daniel Dekany <ddek...@apache.org> wrote: >> Tuesday, August 29, 2017, 3:03:02 PM, Woonsan Ko wrote: >> >>> On Tue, Aug 29, 2017 at 5:00 AM, Daniel Dekany <ddek...@apache.org> wrote: >>>> Tuesday, August 29, 2017, 5:25:31 AM, Woonsan Ko wrote: >>>> >>>>> Hi Daniel, >>>>> >>>>> Thanks for the remarks and hints! Please see my question inline. >>>>> >>>>> On Sat, Aug 26, 2017 at 4:50 AM, Daniel Dekany <ddek...@freemail.hu> >>>>> wrote: >>>>>> Saturday, August 26, 2017, 10:44:03 AM, Daniel Dekany wrote: >>>>>> >>>>>> [snip] >>>>>>> <#macro foo> >>>>>>> <#local status = 'blah'> >>>>>>> <@spring.bind "user.name"> >>>>>>> ${status.value} <#-- Means 'blah'.value, won't work --> >>>>>> >>>>>> To clarify, here I have assumed that spring.bind calls >>>>>> env.setVariable("status", ...) internally. Then the local with the >>>>>> same name shadows that tempolate-namespace scoped variable. >>>>> >>>>> It seems working with env.setVariable("status", ...): >>>>> >>>>> // Excerpt from >>>>> https://github.com/woonsan/incubator-freemarker/blob/feature/FREEMARKER-55-2/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/BindDirective.java >>>> >>>> Looks good. But what are your thoughts on using a nested content >>>> parameter instead? >>> >>> I'm sure I'm missing something or in misunderstandings. I want to try >>> the option using a nested content parameter instead, but I don't know >>> how to do that. ;-) >>> Ideally, <@spring.bind ... /> directive needs to set a local variable >>> called "status" or whatever (if the variable name can be given by a >>> nested content parameter) and developers should be able to use the >>> status variable ("status" or whatever) somehow inside the directive. >>> So, my assumption was, if the parameter is given to the directive, I >>> can probably fill in a variable somehow by resolving the bind status >>> object. I guess I'm totally ignorant on how nested content parameters >>> work with directives... >> >> A directive can't create a nested content variable. The caller can >> declare a nested content parameter, like `<@spring.bind ...; status>`, >> and then the directive can specify the actual value of that parameter >> when it calls the nested content with >> `callPlace.executeNestedContent`. (Of course it's likely that the >> caller will chose a shorter name, like `s`; see earlier mails.) > > Ah, I think I now understand it! > So, for example, if I do this: > > callPlace.executeNestedContent(new TemplateModel [] { status }, out, env); > > , then the nested template may read/use the passed status object by > referring to by the name (e.g, 's') given by themselves, right?
Right. > I totally overlooked the fact that I can pass arguments to the nested > content when invoking #executeNestedContent(). > I'll try it out again. I personally it is better to use nested content > parameters instead of #setVariable() as they are local. > The following example seems a lot better than the JSP taglib to me: > > <@spring.bind "user.email"; status> > <input type="text" name="email" value="${status.value!}" /> > </@spring Looks better to me as well. > Thanks again for the advice! > > Cheers, > > Woonsan > >> >> You may wonder if we should allow the directive to create a nested >> content variable. I think it's a probably a quite bad library design >> if you need that. Creating variables without the caller seeing that >> makes understanding what's going on significantly harder. Worse, that >> magically appearing variable can hide a variable from a higher scope. >> If the caller doesn't ask for the creation of the variable, then that >> variable should be under the `spring` namespace. Of course that >> (`spring.status`) would be more verbose than using a nested content >> parameter, so it doesn't make sense in this case. >> >>> Regards, >>> >>> Woonsan >>> >>>> >>>>> Another question: is it okay to assume that I have a >>>>> DefaultObjectWrapper when this directive is executed and throw an >>>>> exception otherwise? >>>> >>>> At the moment it's enough to expect it to be an >>>> ObjectWrapperAndUnwrapper. FreeMarkerServlet also requires that BTW. >>>> I'm not sure if in the future expecting DefaultObjectWrapper will be >>>> necessary, but hopefully not. (Custom JSP tag support expects a >>>> DefaultObjectWrapper at the moment, for wrapping JSP functions.) >>>> >>>>>> [snip] >>>>>>> With nested content parameter it's also more obvious what's going on, >>>>>>> and if you chose a shorter name it's not that verbose either: >>>>>>> >>>>>>> <@spring.bind "user.name"; s> >>>>>>> ${s.value} >>>>> >>>>> If I choose to use nested content parameter instead of having >>>>> env.setVariable() calls, how can I get access to the parameter, s? >>>>> Can I access it through any argument of the #execute() method in the >>>>> Java code? Any example java code using nested content parameter? >>>> >>>> I'm not sure what you try to achieve. As the nested content parameter >>>> is local to the nested content, similarly as a local variable is local >>>> to the method body in Java, where do you want to access `s` from, and >>>> why? >>>> >>>>> Thanks in advance, >>>>> >>>>> Woonsan >>>>> >>>>>> [snip] >>>>>> >>>>>> Eh... of course the comment is outdated here. It will work in this >>>>>> case. `s` can't be hidden by anyone there, it wouldn't mater if we had >>>>>> <#local s = 'blah'> for example. >>>>>> >>>>>> -- >>>>>> Thanks, >>>>>> Daniel Dekany >>>>>> >>>>> >>>> >>>> -- >>>> Thanks, >>>> Daniel Dekany >>>> >>> >> >> -- >> Thanks, >> Daniel Dekany >> > -- Thanks, Daniel Dekany