web-dev-qa-db-fra.com

Freemarker itérant sur des clés hashmap

Freemarker a deux types de données de collection, des listes et des hashmapsIl existe-t-il un moyen de parcourir les clés de hashmap comme avec les listes?

Donc, si j'ai un var avec des données, disons:

user : {
  name : "user"
  email : "[email protected]"
  homepage : "http://nosuchpage.org"
}

Je voudrais imprimer toutes les propriétés de l'utilisateur avec leur valeur ..__ Ceci n'est pas valide, mais l'objectif est clair:

<#list user.props() as prop>
  ${prop} = ${user.get(prop)}
</#list>
78
tzador

Edit: N'utilisez pas cette solution avec FreeMarker 2.3.25 et plus, en particulier pas .get(prop). Voir d'autres réponses.

Vous utilisez les touches intégrées fonction, par exemple. cela devrait fonctionner:

<#list user?keys as prop>
    ${prop} = ${user.get(prop)}
</#list>  
98
skaffman

Pour votre information, il semble que la syntaxe de récupération des valeurs ait changé en fonction de:

http://freemarker.sourceforge.net/docs/ref_builtins_hash.html

<#assign h = {"name":"mouse", "price":50}>
<#assign keys = h?keys>
<#list keys as key>${key} = ${h[key]}; </#list>
48
Nick Spacek

Depuis la version 2.3.25, procédez comme suit:

<#list user as propName, propValue>
  ${propName} = ${propValue}
</#list>

Notez que cela fonctionne également avec des clés non-chaînes (contrairement à map[key], qui devait alors être écrit en tant que map?api.get(key)).

Avant la version 2.3.25, la solution standard était la suivante:

<#list user?keys as prop>
  ${prop} = ${user[prop]}
</#list>

Cependant, certaines intégrations FreeMarker très anciennes utilisent une configuration étrange, dans laquelle les méthodes publiques Map (telles que getClass) apparaissent en tant que clés. Cela se produit car ils utilisent une variable BeansWrapper (au lieu de DefaultObjectWrapper) dont la propriété simpleMapWrapper a été laissée sur false. Vous devriez éviter une telle configuration, car elle mélange les méthodes avec de vraies entrées Map. Mais si vous rencontrez une telle configuration malheureuse, le moyen d'éviter cette situation consiste à utiliser les méthodes Java exposées, telles que user.entrySet(), user.get(key), etc., et à ne pas utiliser les constructions de langage de modèle telles que ?keys ou user[key].

32
ddekany

Si vous utilisez un BeansWrapper avec un niveau d'exposition Expose.SAFE ou Expose.ALL, l'approche standard Java permettant d'itérer l'ensemble d'entrées peut être utilisée:

Par exemple, ce qui suit fonctionnera dans Freemarker (depuis au moins la version 2.3.19):

<#list map.entrySet() as entry>  
  <input type="hidden" name="${entry.key}" value="${entry.value}" />
</#list>

Dans Struts2, par exemple, une extension de BeanWrapper est utilisée avec le niveau d'exposition par défaut pour permettre ce mode d'itération.

12
rees

Itération d'objets

Si vos clés de carte sont un objet et non une chaîne, vous pouvez l'itérer à l'aide de Freemarker.

1) Convertissez la carte en liste dans le contrôleur:

List<Map.Entry<myObjectKey, myObjectValue>> convertedMap  = new ArrayList(originalMap.entrySet());

2) Itérer la carte dans le modèle Freemarker, en accédant à l’objet dans la clé et l’objet à la valeur:

<#list convertedMap as item>
    <#assign myObjectKey = item.getKey()/>
    <#assign myObjectValue = item.getValue()/>
    [...]
</#list>
2
Tk421

Vous pouvez utiliser un seul devis pour accéder à la clé que vous avez définie dans votre programme Java.

Si vous définissez une carte en Java comme celle-ci 

Map<String,Object> hash = new HashMap<String,Object>();
hash.put("firstname", "a");
hash.put("lastname", "b");

Map<String,Object> map = new HashMap<String,Object>();
map.put("hash", hash);

Ensuite, vous pouvez accéder aux membres de 'hash' dans Freemarker comme ceci -

${hash['firstname']}
${hash['lastname']}

Sortie: 

a
b
1
Ashish Chhabria

Pour être complet, il convient de mentionner qu’il existe depuis peu de temps une gestion correcte des collections vides dans Freemarker.

Ainsi, le moyen le plus pratique de parcourir une carte est:

<#list tags>
<ul class="posts">
    <#items as tagName, tagCount>
        <li>{$tagName} (${tagCount})</li>
    </#items>
</ul>
<#else>
    <p>No tags found.</p>
</#list>

Plus de <#if ...> wrappers.

0
Ondra Žižka