Search code examples
getfreemarkervelocity

can we use .get() in freemarker template?


I am converting velocity template to Freemarker and came across this condition below

=== Velocity Code ===

#if($frm_BenefitIcons.get("$beni.benefitIconNo"))
#set($xxx = $frm_BenefitIcons.get("$beni.benefitIconNo").toString().substring(12).toUpperCase())
#else
#set($xxx = "")
#end

and I converted it to freemarker as

=== Freemarker Code ===

<#if (frm_BenefitIcons.get("${(beni.benefitIconNo)!}"))??>
<#assign xxx = frm_BenefitIcons.get("${(beni.benefitIconNo)!}")?string?substring(12)?upper_case>
<#else>
<#assign xxx = "">
</#if>

is this correct conversion ? apart from using substring. I am getting output only xxx = "" (which is else part of condition) but not actual value (if part of the condition). Velocity code gives output value for xxx.


Solution

  • In short (and assuming your Configuration uses the default ObjectWrapper, or similar), if the argument to get is a String, you should write frm_BenefitIcons[key]. If frm_BenefitIcons is a java.util.Map, you can't even call get. Unless, you explicitly tell that you want to call the Java API of the object: frm_BenefitIcons?api.get(key). This last is also how you could look up with a non-String key (as the [] operator doesn't support that).

    As of the conversion, I think this will be cleaner:

    <#assign benefitIcon = frm_BenefitIcons[beni.benefitIconNo?c]!>
    <#assign xxx = (benefitIcon != '')?then(benefitIcon[12..]?upper_case, "")>
    

    One critical part there is that where you convert a number (beni.benefitIconNo in this case) to a string, you must use ?c, not ?string, nor "${n}". Conversion to string without ?c is subject to localized formatting, like 1234 is possibly formatted to the string "1,234", which will break the lookup for you. ?c formats for Computer audience, as opposed to for human audience, and so avoids any cultural complication.