Re: [SPAM] hash of hash

Daniel Dekany <[email protected]>
Newsgroups gmane.comp.web.freemarker.user
Message-ID <[email protected]>
The problem is not with hash-of-hash... that's supported. It's a much
dumber limitation (historical baggage actually) that you hit here:
FreeMarker language's hash type is not the same as Java's Map, as it
supports string *keys* only. One solution is to use BeansWrapper
instead of the DefaultObjectWrapper

        // Do this where FreeMarker is initialized, i.e., it should
        // run only once in the application life-cycle, and before
        // getting any templates:
        BeansWrapper wrapper = new BeansWrapper();
        wrapper.setSimpleMapWrapper(true);
        cfg.setObjectWrapper(wrapper);

and then Map-s can be used as methods to get the keys

        ${theMap(theKey?int)}

Note that theMap[theKey] will still work if theKey is a string... but
for non-string keys only theMap(theKey) will work. Yeah, it's quite
much a hack, but it works. Also note the ?int thing... that's needed
because the Java Map-s are strict about the numerical types, while
FreeMarker isn't.

The only big problem (for some) is that BeansWrapper is not backward
compatible DefaultObjectWrapper. (Among others, that's why it's not
the default.) Also it doesn't automatically wrap XML and Python
objects (easy to solve that anyway...). But otherwise it's just better
than DefaultObjectWrapper. (Actually, I never used DefaultWrapper.)


Attila, Jonathan, me... this "keys are strings" limitation is probably
one of the most annoying legacies in FreeMarker. So fixing it should
be a high priority. It can't be done in a backward-compatible way, yet
a solution can be provided without breaking BC. How? We should add a
new wrapper anyway, right? You know, one that's a
BeansWrapper(simpleMapWrapper=true) extended with XML wrapping and
Python wrapping, but without all the SimpleWhatever-s of
DefaultObjectWrapper. That new wrapper we should recommend and push in
all the examples, but technically it shouldn't be the default
ObjectWrapper (so we remain BC). And this new wrapper should wrap
java.util.Map-s into TemplateMapModel-s (an interface that doesn't
exist yet), via setting a new option of BeansWrapper
(allowNonStringKeys or something) to true. And the same with Set-s, I
guess...

-- 
Best regards,
 Daniel Dekany


Wednesday, February 10, 2010, 3:42:20 PM, fuss wrote:

> Hello everyone,
>
> I have some simple construction i Java:
>
> class Products{
> Map<String, Map<Integer, Double>> object;
> }
>
> and to get Double value in Java I can use:
>
> for (Food food : products.getFood()) {
>         for (Integer integer : products.getLenghts()) {
>                
> System.out.println(products.getObject().get(food.getName()).get(integer));
>         }
> }
>
> in freemarker when I am trying to use this construction
>
> [#list products.food as food ]
>         [#list products.lenghts as lenghts]
>                 ${products.object[food.name][lenghts]}
>         [/#list]
> [/#list]
>
> I get unexpected Exception:
>
> Expected number, sequence, or string. products.prices[pizza.name] evaluated
> instead to freemarker.template.SimpleHash on line 49, column 35 in
> products.ftl.
> The problematic instruction:
> ----------
==>> ${products.object[food.name][lenghts]} [on line 49, column 33 in
> products.ftl]
> ----------
>
> IS there any way to get hash from hash directly ?
>
> Thanks for help!



------------------------------------------------------------------------------
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.