O Freemarker tem dois tipos de dados de coleção, listas e hashmaps. Existe uma maneira de iterar as chaves de hashmap da mesma forma que fazemos com as listas?
Então, se eu tiver uma var com dados, digamos:
user : {
name : "user"
email : "[email protected]"
homepage : "http://nosuchpage.org"
}
Gostaria de imprimir todas as propriedades do usuário com seus valores. Isso é inválido, mas o objetivo é claro:
<#list user.props() as prop>
${prop} = ${user.get(prop)}
</#list>
java
freemarker
tzador
fonte
fonte
${user[prop]}
como uma abreviaçãouser[prop]
funciona tanto quantoprop
aString
(caso contrário, você precisauser?api.get(prop)
atualmente), mas cuidado, alguns frameworks (como Struts, eu acredito) usam uma configuração obsoleta onde nomes de métodos são misturados comMap
chaves, e se o valor deprops
acontecer a ser um nome de método nouser
objeto Java, você obtém o método em vez do que você quis dizer. É também por isso que nessas configurações legadas eles sempre usamuser.get(prop)
.Para sua informação, parece que a sintaxe para recuperar os valores mudou de acordo com:
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>
fonte
[key]
e.get(key)
existe desde os tempos antigos..get(key)
não é especial para FTL, é apenas chamar aquele método Java público. Mas você só pode usá-lo se o FreeMarker foi configurado para exporMap
métodos.Desde 2.3.25, faça assim:
Observe que isso também funciona com chaves que não sejam strings (ao contrário
map[key]
, que precisavam ser escritas namap?api.get(key)
época).Antes de 2.3.25, a solução padrão era:
No entanto, algumas integrações FreeMarker realmente antigas usam uma configuração estranha, onde os
Map
métodos públicos (comogetClass
) aparecem como chaves. Isso acontece porque eles estão usando um puroBeansWrapper
(em vez deDefaultObjectWrapper
) cujasimpleMapWrapper
propriedade foi deixada ativadafalse
. Você deve evitar tal configuração, pois mistura os métodos comMap
entradas reais . Mas, se você tiver tal configuração infeliz, a maneira de escapar a situação está usando os métodos Java expostas, tais comouser.entrySet()
,user.get(key)
, etc., e não usando as construções de linguagem modelo de como?keys
ouuser[key]
.fonte
${x?nosuchthing}
e passar o mouse sobre ele, a mensagem de erro mostrada dirá qual versão do FreeMarker ele usa. Deve ser2.3.25-incubating
.Se estiver usando um BeansWrapper com um nível de exposição Expose.SAFE ou Expose.ALL, a abordagem Java padrão de iterar o conjunto de entrada pode ser empregada:
Por exemplo, o seguinte funcionará no Freemarker (desde pelo menos a versão 2.3.19):
<#list map.entrySet() as entry> <input type="hidden" name="${entry.key}" value="${entry.value}" /> </#list>
No Struts2, por exemplo, uma extensão do BeanWrapper é usada com o nível de exposição padronizado para permitir essa forma de iteração.
fonte
InvalidReferenceException
quando tentei, enquantomap?keys
trabalhava.freemarker.ext.beans.BeansWrapper
como wrapper de objeto. Caso contrário,Map
s será automaticamente envolvido em umSimpleHash
objeto que não suporta#entrySet()
. (consulte freemarker.sourceforge.net/docs/api/freemarker/template/… )BeansWrapper
, pelo menos não com seus padrões, ondesimpleMapWrapper
estáfalse
. Isso fica muito confuso, pois mistura chaves com nomes de métodos. Se você precisar chamarentrySet()
, apenas continue usando um wrapper de objeto "limpo", como o padrão, e escrevamap?api.entrySet()
se você precisa acessar a API Java em vez das chaves.Iterando objetos
Se as chaves do seu mapa são um objeto e não uma string, você pode iterar usando o Freemarker.
1) Converta o mapa em uma lista no controlador:
List<Map.Entry<myObjectKey, myObjectValue>> convertedMap = new ArrayList(originalMap.entrySet());
2) Iterar o mapa no modelo Freemarker, acessando o objeto na chave e o objeto no valor:
fonte
Para completar, vale a pena mencionar que há um tratamento decente de coleções vazias no Freemarker desde recentemente.
Portanto, a maneira mais conveniente de iterar um mapa é:
<#list tags> <ul class="posts"> <#items as tagName, tagCount> <li>{$tagName} (${tagCount})</li> </#items> </ul> <#else> <p>No tags found.</p> </#list>
Sem mais
<#if ...>
invólucros.fonte
Você pode usar uma aspa simples para acessar a chave que definiu em seu programa Java.
Se você definir um mapa em Java como este
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);
Então você pode acessar os membros do 'hash' no Freemarker assim -
${hash['firstname']} ${hash['lastname']}
Resultado :
fonte