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>
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>
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>
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]
.
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.
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>
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
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.