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

Reply via email to