Null values in Freemarker Template - freemarker

Code:
<if state??>
<ns1:StateName>${state}</ns1:StateName>
</#if>
I want to print the value when state is not null.
Getting this error:
Unexpected directive, "</#if>". Check if you have a valid #if-#elseif-#else structure.
Please help with the solution

<#if state??>
<ns1:StateName>${state}</ns1:StateName>
</#if>

Related

Freemarker - is nested if allowed inside else (not the common if elseif...elseif else)

I am not asking about the common nesting in freemarker (which I know for sure is supported) :
<#if cond1> do abc
<#elseif cond2> do xxx
<#elseif cond3> do yyy
<#else> do zzz
</#if>
Want to know if the below nesting is supported in freemarker:
<#if cond1> do abc
<#else>
<#if cond-X> do xxx </#if>
<#if cond-Y> do yyy </#if>
<#if cond-Z> do zzz </#if>
</#if>
Note that I have multiple if conditions inside the else.
My code throws error
Error detail: Syntax error in template "template" in line 1282, column 45: Unexpected directive, "</#if>". Check if you have a valid #if-#elseif-#else structure.
So I suspect the latter type of nesting provided by my architect.
It is supported, and what you show is parsed successfully for me. Maybe the error is elsewhere, or you aren't looking at the template that's actually processed?

Freemarker assign value to variable

I'm having trouble while trying to assign value to a variable using Freemarker.
<#if size??>
<#assign num=size?number>
<#if (num>0)>
<#list 0..num-1 as i>
<#if .vars['abc'+i?c] = "test">
<#assign .vars['abc'+i?c] = .vars['abc'+i?c]?replace("test","Test")>
</#if>
</#list>
</#if>
This is the error message: Encountered ".", but was expecting one of:
STRING_LITERAL
RAW_STRING
ID
Can anyone help me with this?
Thank you.
You can only write top-level variables in a FreeMarker template. Also you can't assign to a variable with dynamically constructed name, except with an ?interpret hack: <#"<#assign abc${i?c} = abc${i?c}?reaplce('test', "Test")>"?interpret />. Obviously that's horrid... BTW, what's the use case here? Why do you need to assign to dynamically constructed variable names?

does freemarker support show all variable in data-model?

I want to see all variables in freemarker data-model, just like struts2 debug tag to show value stack.
Is there a way for freemarker to do this ?
There's no universal solution possible for that, but you can try
<#list .data_model?keys as key>
${key}
</#list>
This works if the data-model is just a usual Map or JavaBean, but for more sophisticated data-models it's up to the data-model implementation if it supports ?keys and if it indeed returns everything.
You also have the variables that you set in the templates, which can be listed like above, only instead of .data_model use .globals, .namespace (which means the current template namespace) and .locals.
You may also have Configuration-level shared variables, and there's no way to list those purely from FTL (you could write a custom TemplateMethodModel for it that reads Configuration.getSharedVariableNames() though, and call it from the template).
Of course, ideally, FreeMarker should have a <#show_variables> directive or something, that does a best effort to show all this... but sadly there is no such thing yet.
An even more detailed way would be this macro:
<#macro dump_object object debug=false>
<#compress>
<#if object??>
<#attempt>
<#if object?is_node>
<#if object?node_type == "text">${object?html}
<#else><${object?node_name}<#if object?node_type=="element" && object.##?has_content><#list object.## as attr>
${attr?node_name}="${attr?html}"</#list></#if>>
<#if object?children?has_content><#list object?children as item>
<#dump_object object=item/></#list><#else>${object}</#if> </${object?node_name}></#if>
<#elseif object?is_method>
#method
<#elseif object?is_sequence>
[<#list object as item><#dump_object object=item/><#if !item?is_last>, </#if></#list>]
<#elseif object?is_hash_ex>
{<#list object as key, item>${key?html}=<#dump_object object=item/><#if !item?is_last>, </#if></#list>}
<#else>
"${object?string?html}"
</#if>
<#recover>
<#if !debug><!-- </#if>LOG: Could not parse object <#if debug><pre>${.error}</pre><#else>--></#if>
</#attempt>
<#else>
null
</#if>
</#compress>
</#macro>
<#dump_object object=.data_model/>
This gives you a full dump of your data model.
Here is #lemhannes macro definition modified to emit JSON. Lightly tested on a fairly simple datamodel
<#macro dump_object object debug=false>
<#compress>
<#if object??>
<#attempt>
<#if object?is_node>
<#if object?node_type == "text">${object?json_string}
<#else>${object?node_name}<#if object?node_type=="element" && object.##?has_content><#list object.## as attr>
"${attr?node_name}":"${attr?json_string}"</#list></#if>
<#if object?children?has_content><#list object?children as item>
<#dump_object object=item/></#list><#else>${object}</#if>"${object?node_name}"</#if>
<#elseif object?is_method>
"#method"
<#elseif object?is_sequence>
[<#list object as item><#dump_object object=item/><#if !item?is_last>, </#if></#list>]
<#elseif object?is_hash_ex>
{<#list object as key, item>"${key?json_string}":<#dump_object object=item/><#if !item?is_last>, </#if></#list>}
<#else>
"${object?string?json_string}"
</#if>
<#recover>
<#if !debug>"<!-- </#if>LOG: Could not parse object <#if debug><pre>${.error}</pre><#else>-->"</#if>
</#attempt>
<#else>
null
</#if>
</#compress>
</#macro>

Handling null values in Freemarker

How to handle null values in Freemarker? I get some exceptions in the template when null values are present in data.
Starting from freemarker 2.3.7, you can use this syntax :
${(object.attribute)!}
or, if you want display a default text when the attribute is null :
${(object.attribute)!"default text"}
You can use the ?? test operator:
This checks if the attribute of the object is not null:
<#if object.attribute??></#if>
This checks if object or attribute is not null:
<#if (object.attribute)??></#if>
Source: FreeMarker Manual
I think it works the other way
<#if object.attribute??>
Do whatever you want....
</#if>
If object.attribute is NOT NULL, then the content will be printed.
Use ?? operator at the end of your <#if> statement.
This example demonstrates how to handle null values for two lists in a Freemaker template.
List of cars:
<#if cars??>
<#list cars as car>${car.owner};</#list>
</#if>
List of motocycles:
<#if motocycles??>
<#list motocycles as motocycle>${motocycle.owner};</#list>
</#if>
I would like to add more context if you have issues and this is what I have tried.
<#if Recipient.account_type?has_content>
… (executes if variable exists)
<#else>
… (executes if variable does not exist)
</#if>
This is more like Javascript IF and ELSE concept where we want to check whether this value or another chaining through required logic.
Freemarker webite
Other reference:
Scenario: Customer has ID and name combined like 13242 Harish, so where our stakeholder need the only name, so I have tried this ${record.entity?keep_after(" ")} and it did work, however, it can only work when you have space, but when a customer doesn't have space and one name, I had to do some IF ELSE condition to check Null value.
Use:
${(user.isSuperman!false)?c}
It will work when "isSuperman" is null and when have boolean value
What we want:
For "null" we want to output 'false'
For boolean value and want to output value ('true' or 'false')
What we know:
boolean need to convert to string by using "?c" see Built-ins for booleans
but null we cannot convert to string and we need to use "!" see Handling missing values

regular expression in freemarker to check if first character in a string is lower case

I am using freemarker to generate a Java class. I am stuck to convert a first character of a string to lower case.
Following is what i tryed but no luck :(
<#function methodName attName >
<#if attName?length > 1 >
<#if attrName(0)?matches([a-z])>
<#return attName>
</#if>
</#if>
</#function>
Thanks.
Try uncap_first:
${"Test"?uncap_first} yields test

Resources