Wednesday, April 18, 2018, 4:06:27 AM, Woonsan Ko wrote:
> Sorry for late reply. Please see my comments inline.
>
> On Mon, Apr 9, 2018 at 4:14 PM, Daniel Dekany <[email protected]> wrote:
>> Monday, April 9, 2018, 8:34:27 PM, Woonsan Ko wrote:
>>
>>> Hi,
>>>
>>> While trying to implement directives to replace Spring MVC select,
>>> options and option tags [1], I'm wondering what is the best to nest
>>> options or option directive inside form directive.
>>
>> Or, you mean the "select" directive?
>>
>>> One straightforward option is:
>>>
>>> <@form.select 'user.favoriteSport'; form>
>>> <@option form value="NONE" label="--- Select ---" />
>>> <@options form items=sports />
>>> </@form>
>>>
>>> As we don't have something like
>>> javax.servlet.jsp.tagext.TagSupport#findAncestorWithClass(Tag, Class)
>>
>> Yeah, and we should have that. This is something that's missing from
>> FM2 for a long time too... it's in my "most frequently missed
>> features" FM2 TODO list. Maybe in 2.3.29.
>>
>>> (bottom to top), we can pass the form directive model to the nested
>>> content like org.apache.freemarker.spring.model.BindDirective does
>>> already (top to bottom).
>>
>> No way, that's way too awkward for the user (especially if you
>> consider factoring out <@option ... />-s into macros). For now you
>> should just use Environment.getCustomState(CustomStateKey) to maintain
>> some state object where you keep track of the current context. (The
>> main problem with that feature is that there's no template language
>> feature to access it. Like you can't write two macros that exchange
>> information through that, purely in the template language. But in your
>> case that's not a problem, as you implement everything in Java.)
>
> I want to make the select directive model accessible from a nested
> options or option directive model. So I was thinking of something like
> the following in the select directive:
>
> // create a custom state key to return this
> final CustomStateKey<SelectTemplateDirectiveModel>
> selectCustomStateKey = new
> CustomStateKey<SelectTemplateDirectiveModel>() {
> @Override
> protected SelectTemplateDirectiveModel create() {
> return SelectTemplateDirectiveModel.this;
> }
> };
> // pass the custom state key
> env.getCustomState(selectCustomStateKey);
> // execute nested content such as options or option
> callPlace.executeNestedContent(null, out, env);
> // snip
> // write output...
>
> Question is, how can I retrieve the selectCustomStateKey in the nested
> option(s) directive?
> Environment#getCustomState(CustomStateKey<T>) requires that the nested
> directive should have the CustomStateKey instance already somehow.
The CustomStateKey<T> JavaDoc says:
/**
* Used with {@link CustomStateScope}-s; each subclass must have exactly one
instance, which should be stored in
* a static final field. So the usual usage is like this:
*
* <pre>
* static final CustomStateKey MY_STATE = new CustomStateKey() {
* @Override
* protected Object create() {
* return new ...;
* }
* };
* </pre>
*/
That's why you know the key; it's *static* final value.
The object that it stores should be something like a
FreemarkerSpringScope (maybe not the best name, just a quick example),
and it should have a mutable property like selectDirectiveInContext.
The assumption is that generally there will be more such properties.
Then you don't define a key for each such property, and doesn't get
them individually with getCustomScope. Instead, you only have a single
key, and you get your scope object with it. Everything else
conveniently happens through the Java API of your scope object.
> I wonder how to do that easily without any hacky solutions such as
> thread local. servlet request attributes could be the last resort,
> but doesn't sound good to me either. Could you shed a light here?
>
> Regards,
>
> Woonsan
>
>>
>>> So, developers are needed to pass it along like the above example,
>>> unless it is as simple as one-liner like the following:
>>>
>>> <@form.select 'user.favoriteSport' items=sports />
>>>
>>> Does it sounds good? Or do you have any better ideas?
>>>
>>> Regards,
>>>
>>> Woonsan
>>>
>>> [1] https://www.mkyong.com/spring-mvc/spring-mvc-dropdown-box-example/
>>>
>>
>> --
>> Thanks,
>> Daniel Dekany
>>
>
--
Thanks,
Daniel Dekany