FreeMarker if statement comparing two values - freemarker

I'm trying to compare two values
<#if user.cellPhone != changedUser.cellPhon>
<br><span class="changes">*${changedUser.cellPhone}</span></#if>
I'm getting an error
freemarker.core.InvalidReferenceException: The following has evaluated to null or missing:==> changeUser
Tip:
If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??

Add null check to condition changedUser??:
<#if changedUser?? && user.cellPhone != changedUser.cellPhon>

Related

Trying to generate a string that becomes a variable name in Freemarker or a "derived variable name"

I'm using a data-directive or list to pull in several values, of which, I don't know how many there will be, and I want to try and list through them, and create several variables in the list if you will.
<#list 1..10 as x>
<#-- the next line doesn't work, but what i'm trying to fix -->
<#assign .vars['VAR'+x?string] = rand(100) />
</#list>
But I can list them back out that way.
<#list 1..10 as x>
${.vars['VAR'+x?string]}
</#list>
The documentation for assign, says:
name: name of the variable. It is not expression. However, it can be
written as a string literal, which is useful if the variable name
contains reserved characters, for example <#assign "foo-bar" = 1>.
Note that this string literal does not expand interpolations (as
"${foo}").
Is there no way around this? Am I trying to do the impossible? Is there some way I can insert a derived name into the .vars... Hash is it?
A little more research that was close, but didn't get me there:
This prevoius question gives how to READ the derived variable, but I need to WRITE/CREATE the derived variable.
FreeMarker get variable value by concatenating another variable value
This prevoius question shows that I can use a string to assign a variable and re-iterates what we saw in the first link.
Variable name in Freemarker Template Language
As FreeMarker can't assign to elements of collections (but you can ?map(it -> ...) a collection to another), the only way is via ?interpret:
<#list 1..10 as x>
<#-- the next line doesn't work, but what i'm trying to fix -->
<#'<#assign VAR${x?c} = rand(100)>'?interpret />
</#list>
I wonder why do you need to assign to a dynamically named variables though, since reading dynamically named variables is also a pain, even if a lesser one.
Ultimately, I believe the correct way to phrase my solution was a sequence of hashes:
<#list 1..z_Coupon_Pet.NUM_COUPONS as x>
<#assign INSTORE_COUPON=call_coupon_from_table1() />
<#assign ONLINE_COUPON=call_coupon_from_table2() />
<#assign coupon_string_row= '{
"COUPON_NUM" : ${x},
"INSTORE" : "${INSTORE_COUPON?js_string}",
"ONLINE" : "${ONLINE_COUPON?js_string}"
}' />
<#if x==1>
<#assign coupon_hash_string = coupon_string_row />
<#else>
<#assign coupon_hash_string = coupon_hash_string + ',' + coupon_string_row />
</#if>
</#list>
</#if>
<#if coupon_hash_string?has_content>
<#assign coupon_hash=parsejson('[' + coupon_hash_string + ']') />
</#if>
We specifically avoid <#assign my_hash = my_hash + element /> because of this note in the documentation:
Note that hash concatenation is not to be used for many repeated concatenations, like for adding items to a hash inside a loop. While adding together hashes is fast and is constant time (independent of the size of the hashes added), the resulting hash is a bit slower to read than the hashes added together. Thus after tens... of additions the result can be impractically slow to read.

Freemarker, looping sequence with one object/multiple attributes

I am working on looping through one object with multiple attributes. In my scenario, I am looking for external content values.
email_address
article01
article02
article03
email#address.com
Y
Y
These values can change all the time, so we have to define them manually every instance where we use this, but I want to be able to list them in a sequence and then loop through and include them when object.attribute=Y.
The below block is purely conceptual, but referencing the attribute within the expression is where I get confused.
<#assign seq = ['article01','article02','article03']>
<#list seq as articles>
<#if base.${article}="Y">
<#include "*/${article}.htm"/>
</#if>
</#list>
In this instance, the resulting code would be:
<html><article01.html content></html>
<html><article03.html content></html>
Assuming base.articel01 would work, you can use base[article] (instead of base.${article}).

How can I check null and empty both in freemarker string?

For example.
String s can have these values like "value", "" or null.
<#if str?? && str?has_content>
${str}
</#if>
Can I check ??(null) and ?has_content(empty not null) both value in freemarker if statement not using TemplateModel?
str?has_content returns true if str is non-null (non-missing), and is also not a 0-length string. So you just need <#if str?has_content>.
(As of TemplateModel-s, every value is a TemplateModel as far as templates see. There's no such thing as a non-TemplateModel value.)

If statement inside checked attribute of input element in freemarker?

Is it possible to write this in freemarker.
<input type="checkbox" value="Available ?" checked="<#if ${status}=='Available'>true<#else>false</#if>"/>
For now it throws exception
I want html checkbox to be checked if status property equals to "Available".
How to do this in freemarker?
<#if ${status}=='Available'> has a syntactical error (that the error message that you haven't included points to, I'm certain): you can't use ${...} inside FreeMarker tags (well, except inside string literals, but whatever). It should be just <#if status == 'Available'>. But, the simples solution for what you want is:
checked="${(status == 'Available')?c}"
or if you have an older FreeMarker then:
checked="${(status == 'Available')?string('true', 'false')}"

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

Resources