Pregunta Freemarker iterando sobre claves hashmap


Freemarker tiene dos tipos de datos de recopilación, listas y hashmaps ¿Hay alguna forma de iterar sobre las claves hashmap tal como lo hacemos con las listas?

Entonces, si tengo una var con datos, digamos:

user : {
  name : "user"
  email : "looser@everything.com"
  homepage : "http://nosuchpage.org"
}

Me gustaría imprimir todas las propiedades del usuario con su valor. Esto no es válido, pero el objetivo es claro:

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

76
2017-09-30 12:22


origen


Respuestas:


Editar: No use esta solución con FreeMarker 2.3.25 y superior, especialmente no .get(prop). Ver otras respuestas

Usas el built-in llaves función, p. Esto debería funcionar:

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

94
2017-09-30 12:27



FYI, parece que la sintaxis para recuperar los valores ha cambiado de acuerdo con:

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>

47
2018-03-30 17:24



Desde 2.3.25, hazlo así:

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

Tenga en cuenta que esto también funciona con teclas que no son de cadena (a diferencia map[key], que tenía que escribirse como map?api.get(key) entonces).

Antes de 2.3.25, la solución estándar era:

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

Sin embargo, algunas integraciones de FreeMarker muy antiguas usan una configuración extraña, donde el público Map métodos (como getClass) aparecen como llaves. Eso sucede ya que están usando un puro BeansWrapper (en lugar de DefaultObjectWrapper) cuyo simpleMapWrapper la propiedad fue dejada en false. Debe evitar una configuración de este tipo, ya que mezcla los métodos con real Map entradas. Pero si se encuentra con una configuración tan desafortunada, la forma de escapar de la situación es usar los métodos expuestos de Java, como user.entrySet(), user.get(key), etc., y no usa los constructos de lenguaje de plantilla como ?keys o user[key].


24
2017-07-08 17:25



Si usa un BeansWrapper con un nivel de exposición de Expose.SAFE o Expose.ALL, se puede emplear el enfoque estándar de Java para iterar el conjunto de entradas:

Por ejemplo, lo siguiente funcionará en Freemarker (desde al menos la versión 2.3.19):

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

En Struts2, por ejemplo, una extensión de BeanWrapper se usa con el nivel de exposición predeterminado para permitir esta forma de iteración.


12
2018-05-07 14:48



Iterar objetos

Si las claves de su mapa son un objeto y no una cadena, puede iterar utilizando Freemarker.

1) Convierta el mapa en una lista en el controlador:

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

2) Iterar el mapa en la plantilla de Freemarker, acceder al objeto en la clave y el objeto en el valor:

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

2
2018-06-20 08:42



Puede usar una comilla simple para acceder a la clave que estableció en su programa Java.

Si configura un mapa en 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);

Entonces puedes acceder a los miembros de 'hash' en Freemarker de esta manera:

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

Salida:

a
b

1
2018-03-19 18:28



Para completar, vale la pena mencionar que hay un manejo decente de colecciones vacías en Freemarker desde hace poco.

Entonces la forma más conveniente de iterar un mapa es:

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

No más <#if ...> envoltorios.


0
2017-07-23 16:09