Re: map?get(nonStringKey) for FM 2.3.x?
Denis Bredelet <[email protected]>
| Newsgroups | gmane.comp.web.freemarker.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi Daniel, > FTL has this annoying problem that it has no type that corresponds to > Java's Map. It has a type called hash, but it was introduced for > variable hierarchies (like `user.name`), so the keys are limited to > stings. For some reason TemplateMapModel wasn't introduced, instead, > the bundled wrappers wrap Map-s as hashes, which of course doesn't > work for non-string keys. Except, if you call the Map.get method > directly from the template, but since FTL doesn't use separate > name-spaces for plain sub-variables and methods, if Map methods are > exposed, they mix with the actual string keys, which is a mess, so by > default Map methods are hidden. Luckily, with BeansWrapper, you can > just do `someMap(nonStringKey)`, but sadly, BeansWrapper is not used > by default for wrapping Map-s, they are wrapped into a SimpleHash > instead. What is wrong with Beans Wrapper approach? > > So the user asks how to get an item from this map with a non-String > key, and we don't have a simple answer. You need to use BeansWrapper > instead of the default... oh, but wait, switching wrapper might breaks > your application, and depending on the framework there's possibly no > way to set the object wrapper at all. How to fix this situation: > > - Ultimately, add TemplateMapModel, and a new recommended > ObjectWrapper that uses it too. Unfortunately, this is not an option > for existing applications and frameworks, unless they willing to > review their templates. > > - SimpleHash should implement TemplateMethodModelEx, so > `someMap(nonStringKey)` works for SimpleHash-wrapped templates too. > My problem with this is that calling a map like a method is quite > confusing for most programmers. You look at the template, and > believe that "someMap" is primarily a function. But it's a Map. > Also adding TemplateMethodModelEx to SimpleHash can break existing > applications with a small chance. I want to see a concrete demonstration of the problems with this solution. Personally I think it would work well. How is it confusing? What does it break? Thanks, -- Denis. > > - Add `get` as built-in, which will utilize its knowledge of the > bundled wrappers to get to the Map behind. No mater how "someMap" > was wrapped, if there's a Map behind, `someMap?get(key)` just works. > If the wrapper is not recognized, nor AdapterTemplateModel is > implemented, it can still call TemplateHashModel.get(String) and give > an error for a non-String key. > > -- > Best regards, > Daniel Dekany ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/