On Wed, Apr 18, 2018 at 10:07 AM, Daniel Dekany <ddek...@apache.org> wrote: > 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 <ddek...@apache.org> 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.
Ah I see. Use the same key, but it's scoped to the Environment in my case. Gotcha. Thank you so much. Cheers, Woonsan > >> 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 >