0
votes

I have a HashMap<Integer, String> called lookup that is provided by an Object I want to render in a Freemarker template.

Here's the Java class:

public class SearchResultContainer implements Container<T> {
    private final Map<Integer, String> lookup;
    private final List<T> items;

    public SearchResultContainer(List<T> items, Map<Integer, String> lookup) {
        this.lookup= lookup;
        this.items = items;
    }

    @Override
    public List<T> getItems() {
        return items;
    }

    public Map<Integer, String> getLookup() {
        return this.lookup;
    }
}

I tried to access the values of the map like this:

<#-- @ftlvariable name="self" type="SearchResultContainer" -->
<#assign lookup=self.lookup/>
<#if lookup?has_content>
  <#list lookup?keys as key>
    ${key} = ${lookup[key])}
  </#list>
<#/if>

I get this error:

For "...[...]" left-hand operand: Expected a sequence or string or something automatically convertible to string (number, date or boolean), but this has evaluated to an extended_hash (HashMap wrapped into f.t.DefaultMapAdapter):
==> lookup [in template [...]
[...]
Tip: You had a numberical value inside the []. Currently that's only supported for sequences (lists) and strings. To get a Map item with a non-string key, use myMap?api.get(myKey).
[...]

Then I tried to use ?api as suggested:

<#list lookup?keys as key>
    ${key} = ${lookup?api.get(key)}
</#list>

And I get this error:

Can't use ?api, because the "api_builtin_enabled" configuration setting is false. Think twice before you set it to true though. Especially, it shouldn't abused for modifying Map-s and Collection-s.
The blamed expression:
==> lookup?api [in template [...]

Is there any other way to access the map, than to provide an additional method in my SearchResultContainer class, or enabling api_builtin_enabled, which is not suggested?

1

1 Answers

0
votes

Just enable the api built-in. The reason you should give it some though is that it can be abused (obviously), which can be a problem where the template authors aren't fully trusted. The reason it's not enabled by default is that ?api didn't exist in much earlier versions, so it must be an op-in feature due to the security consequences.