Freemarker a deux types de données de collection, des listes et des hashmaps. Existe-t-il un moyen d'itérer sur les clés de hashmap comme nous le faisons 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 souhaite imprimer toutes les propriétés de l'utilisateur avec leur valeur. Ce n'est pas valide, mais l'objectif est clair:
<#list user.props() as prop>
${prop} = ${user.get(prop)}
</#list>
java
freemarker
tzador
la source
la source
${user[prop]}
comme sténographieuser[prop]
fonctionne aussi loin queprop
c'est aString
(sinon vous en avez besoinuser?api.get(prop)
actuellement), mais attention, certains frameworks (comme Struts, je crois) utilisent une configuration maintenant obsolète où les noms de méthode sont mélangés avec desMap
clés, et donc si la valeur deprops
arrive à être un nom de méthode dans l'user
objet Java, vous obtenez la méthode au lieu de ce que vous vouliez dire. C'est aussi pourquoi dans ces anciennes configurations, ils utilisent toujoursuser.get(prop)
.Pour info, il semble que la syntaxe de récupération des valeurs a changé selon:
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>
la source
[key]
et.get(key)
existe depuis les temps anciens..get(key)
n'est pas spécial pour FTL, il appelle simplement cette méthode Java publique. Mais vous ne pouvez l'utiliser que si FreeMarker a été configuré pour exposer desMap
méthodes.Depuis 2.3.25, faites-le comme ceci:
Notez que cela fonctionne également avec des clés sans chaîne (contrairement à
map[key]
, qui devait être écrite commemap?api.get(key)
alors).Avant 2.3.25, la solution standard était:
Cependant, certaines intégrations FreeMarker vraiment anciennes utilisent une configuration étrange, où les
Map
méthodes publiques (commegetClass
) apparaissent comme des clés. Cela se produit lorsqu'ils utilisent un purBeansWrapper
(au lieu deDefaultObjectWrapper
) dont lasimpleMapWrapper
propriété a été laissée activefalse
. Vous devriez éviter une telle configuration, car elle mélange les méthodes avec desMap
entrées réelles . Mais si vous avez cette configuration malheureuse, le moyen d'échapper à la situation en utilisant les méthodes Java exposées, telles queuser.entrySet()
,user.get(key)
, etc., et ne pas utiliser les constructions de langage de template comme?keys
ouuser[key]
.la source
${x?nosuchthing}
et que vous survolez, le message d'erreur affiché indiquera quelle version de FreeMarker il utilise. Ça devrait être2.3.25-incubating
.Si vous utilisez un BeansWrapper avec un niveau d'exposition Expose.SAFE ou Expose.ALL, l'approche Java standard d'itération de 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 du BeanWrapper est utilisée avec le niveau d'exposition par défaut pour permettre cette manière d'itération.
la source
InvalidReferenceException
quand je l'ai essayé, pendant que jemap?keys
travaillais.freemarker.ext.beans.BeansWrapper
comme wrapper d'objet. Sinon,Map
s sera automatiquement enveloppé dans unSimpleHash
objet qui ne prend pas en charge#entrySet()
. (voir freemarker.sourceforge.net/docs/api/freemarker/template/… )BeansWrapper
, du moins pas avec ses valeurs par défaut, oùsimpleMapWrapper
estfalse
. Cela devient très déroutant, car il mélange des clés avec des noms de méthodes. Si vous avez besoin d'appelerentrySet()
, continuez simplement à utiliser un wrapper d'objet "propre", comme celui par défaut, et écrivezmap?api.entrySet()
si vous avez besoin d'accéder à l'API Java au lieu des clés.Objets itératifs
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 une liste dans le contrôleur:
List<Map.Entry<myObjectKey, myObjectValue>> convertedMap = new ArrayList(originalMap.entrySet());
2) Itérez la carte dans le modèle Freemarker, en accédant à l'objet dans la clé et à l'objet dans la valeur:
la source
Pour être complet, il convient de mentionner qu'il existe une gestion décente des collections vides dans Freemarker depuis récemment.
Le moyen le plus pratique d'itérer une carte est donc:
<#list tags> <ul class="posts"> <#items as tagName, tagCount> <li>{$tagName} (${tagCount})</li> </#items> </ul> <#else> <p>No tags found.</p> </#list>
Fini les
<#if ...>
emballages.la source
Vous pouvez utiliser un guillemet simple pour accéder à la clé que vous avez définie dans votre programme Java.
Si vous définissez une carte en Java comme ceci
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']}
Production :
la source