The map in JAVA CODE
Map dataMap = new HashMap();
dataMap.("key1","value1");
dataMap.("key2","value2");
dataMap.("key3","value3");
dataMap.("key4","value4");
and freemarker
template.process(dataMap, out);
In the FTL
<#list dataMap.keySet() as k>
<span>${k}:</span><span>dataMap[k]</span>
</#list>
I got the error:
freemarker.core.InvalidReferenceException: Expression dataMapis undefined
So how can I get the value of "key1","key2","key3" and "value1","value2","value3" in the FTL?
I tried to use "rootMap",".main",".vars" to replace "dataMap".All invalid.
You can use the .dataModel special variable like this:
<#list .data_model?keys as prop>
${prop} - ${.data_model[prop]}
</#list>
See the freemarker documentation.
Related
I need to assign an escaped ${expression} to a variable in Freemarker
From the question here, it's clear that we can escape the $ sign in this way
${r"${expression}"}
This works perfectly outside Freemarker context, but doesnot working inside. I am trying to do
<#assign x = "${r"${expression}"}">
But getting the following error:
Template inclusion failed:
You can't use "${" here as you are already in FreeMarker-expression-mode. Thus, instead of ${myExpression}, just write myExpression. (${...} is only needed where otherwise static text is expected, i.e, outside FreeMarker tags and ${...}-s.)
What is the way to achieve this? Thanks in advance.
I had to spent some time to figure out the following scenarios to escape ${expression} -
In Freemarker assignment:
<#assign var = r"${expression}">
In html attribute:
Some link
In Freemarker concatenation:
<#assign x = "something&"+r"${expression}"/>
Like this:
<#assign x = r"${expression}">
I have an addNewRow() method that returns a object which gets displayed through the Freemarker template. There is a scenario where I need to check if one of the fields of the returning object has the value of -1. I tried the following syntax unsuccessfully.
<#if ${Object.field} ==-1>
<#if Object.field ==-1>
How can I access the object variable in this case?
Let's say I have some object container in a freemarker variable and container.content gives me a sequence of objects (I will call them "things") with names and a String getName() accessor. I would like to produce a comma-separated list of the names from the container.content sequence.
If I already had a sequence of names instead of a sequence of things with names, I could simply do names?join(", "). Is there something concise to extract the .name-s from container.content and join them afterwards? More generally, I am looking for a functional programming map (collect, projection) operation, but did not find one in the docs.
What I have tried for now:
Currently, I have <#list container.content as x>${x.name}<#if x?has_next>, </#if></#list> to reproduce that map-then-join operation, but I find that rather verbose and it looks like a smell to me to have basically reimplemented join.
Previously I had container.content?join(", ") and I got "Thing[name=A, otherStuff=...], Thing[name=B, otherStuff=...]" instead of "A, B", of course. I do not wish to modify that Thing#toString method to only return the name instead. I would like to keep that detailed representation for debugging purposes.
You can create function which will extract key values from input sequence:
<#function map seq key>
<#assign result = []>
<#list seq as item>
<#assign result = result + [item[key]]>
</#list>
<#return result>
</#function>
And then use it like that:
${map(container.content, "name")?join(", ")}
I am absolutly new in FreeMarker and I have the following problem working on a Spring MVC application that use this template engine.
So into a controller method I put an int representing the current year (2016) into the model, in this way:
model.addAttribute("annoCorrente", annoCorrente);
Then, into my FreeMarker page I have to assign this value to a variable, so I write the following expression:
<#assign a = ${annoCorrente}>
But in this way I obtain the following error message:
[col. 86] You can't use "${" here as you are already in FreeMarker-expression-mode. Thus, instead of ${myExpression}, just write myExpression. (${...} is only needed where otherwise static text is expected, i.e, outside FreeMarker tags and ${...}-s.)
Why? How can I correctly initizialize a FreeMarker variable with the value obtained from the model associated to this view?
Change <#assign a = ${annoCorrente}> to <#assign a = annoCorrente>
(or you can do <#assign a = "${annoCorrente}"> but this is not recommended)
I'm trying to check if a map contains a value to conditionally execute some freemarker code. This is what I've got so far:
<#if productLayout.layoutWidgetConfiguration[pos.id]??>
<#assign configId>${productLayout.layoutWidgetConfiguration[pos.id]}</#assign>
<#else>
<#assign configId></#assign>
</#if>
But I get this error, which basically fails the if condition.
Error executing FreeMarker template freemarker.core.UnexpectedTypeException: For "...[...]" left-hand operand: Expected a sequence or string (or something that's implicitly convertible to string), but this evaluated to an extended_hash (wrapper: f.t.SimpleHash):
==> productLayout.layoutWidgetConfiguration [in template "admin/pages/catalog/products/partials/productLayoutEditorRefreshZone.ftl" at line 7, column 22]
The failing instruction (print stack trace for 9 more):
==> #if productLayout.layoutWidgetConfigu... [in template "admin/pages/catalog/products/partials/productLayoutEditorRefreshZone.ftl" at line 7, column 17]
at freemarker.core.DynamicKeyName.dealWithNumericalKey(DynamicKeyName.java:141) ~[DynamicKeyName.class:2.3.20]
How can I check if a value exists in a map in a freemarker template?
Update Here:
It seems the hash doesn't like a Long key value if I change it to this, the if check works, but the value doesn't get retrieved even when it exists - so I guess the question now is how to retrieve a value from a hash with a java.lang.Long key?
<#assign configId = "">
<#if productLayout.layoutWidgetConfiguration[pos.id?string]?has_content>
Hello
<#assign configId = productLayout.layoutWidgetConfiguration[pos.id?string]>
</#if>
<h1>${pos.id}</h1>
[] only supports string hash (Map, etc.) keys and numerical sequence (List, array, etc.) indexes. For now the solution is not using [] for Map-s with non-String keys. You can use the Java API of the object instead, like myMap?api.get(nonStringKey), etc. Note that ?api has to be allowed in the configuration; see http://freemarker.org/docs/ref_builtins_expert.html#ref_buitin_api_and_has_api for more.