Freemarker template string util that can create n number of characters or from a string? - freemarker

is there a string util can can do something like this
<#assign junk="repeatMe"/>
${string.utils.repeat(junk,2)}
OUTPUT:
repeatMerepeatMe

You can do something like this:
<#assign junk = "repeatMe" />
<#list 0..1 as x>${junk}</#list>

Related

String replace in FTL with a specific word

I need to replace a specific string in a URL in FTL.
Code 1:
<#assign pageUrlWithParams= "https://sample.com/category?filter=low&navParam=Appliances&skrLocale=en_US&t=1"/>
<#if pageUrlWithParams?? && pageUrlWithParams != '' && pageUrlWithParams?contains("skrLocale")>
<#assign pageUrlWithParams = pageUrlWithParams?replace('skrLocale','')/>
</#if>
${pageUrlWithParams}
Code 2 :
<#assign pageUrlWithParams= "https://sample.com/category?filter=low&navParam=Appliances&skrLocale=en_FR&t=2"/>
<#if pageUrlWithParams?? && pageUrlWithParams != '' && pageUrlWithParams?contains("skrLocale")>
<#assign pageUrlWithParams = pageUrlWithParams?replace('skrLocale','')/>
</#if>
${pageUrlWithParams}
I need to remove "skrLocale=en_US" and "skrLocale=en_FR" from pageUrlWithParams.
Known text is "skrLocale", using this I need to remove "skrLocale=en_US" and "skrLocale=en_FR".
Because of en_US and en_FR, i dont know how to take that that part after equals.
Some suggest an answer please. Thanks in advance
Using regular expressions ('r' as 3rd parameter to ?replace) is the key. Note that due to the complexity of URL syntax, we need to handle two edge cases (skrLocale is the first parameter, and skrLocale is the only parameter), which the below function fulfills. However, it doesn't handle %xx escapes in the parameter name (which you might don't care about):
<#function removeSkrLocale url>
<#return url?replace(r'([&\?])skrLocale=[^&]*&?', '$1', 'r')?remove_ending('?')>
</#function>
${removeSkrLocale(pageUrlWithParams)}
Of course you can do this without #function as well, directly inside the ${}, but it's reusable and more self documenting this way.
I would use a Freemarker function (this is a simple version, can be improved)
<#function remove_param_if_value_equals pageUrlWithParams paramName, paramValues >
<#if pageUrlWithParams?has_content && pageUrlWithParams?contains(paramName)>
<#list paramValues as paramValue>
<#local paramNameAndValue = paramName + "=" + paramValue />
<#local pageUrlWithParams = pageUrlWithParams?replace(paramNameAndValue,'')/>
</#list>
</#if>
<#return pageUrlWithParams />
</#function>
<#assign pageUrlWithParams= "https://sample.com/category?filter=low&navParam=Appliances&skrLocale=en_US&t=1"/>
<#assign pageUrlWithParams = remove_param_if_value_equals(pageUrlWithParams, "skrLocale", ["en_US", "en_FR"]) />
${pageUrlWithParams}
The code that does the business remains isolated and can be altered/improved later on.
(For example there is that double "&" that could be cleaned)
I don't know about FTL. But if you need to replace parameter skrLocale in your URL, I think below is good pattern you can use:
(skrLocale(.*?)&)
With (.*?) is called lazy, it match from skrLocale to nearest &. Therefore, with your case, it will match skrLocale=en_US& and skrLocale=en_FR& .

Freemarker - How to put variables in hashmap?

I searched the web to find how to add some entries into an existing hashmap.
Consider this code:
<#assign foo={'bar':'go'}>
I want to add a new entry and have something like this:
foo={'bar':'go','new':'entry}
How can I do that?
Using concatenation:
<#assign foo=foo+{'new':'entry'}>
print the hashmap:
<#list foo?keys as k>
${k}: ${foo[k]} <br>
</#list>
The result is exactly what you want:
bar: go
new: entry
D.

freemarker how to use split in string which is readed with include

<#assign reasonValue="xxx.ftl">
and I call it like:
<#include "${reasonValue}">
and I get output like:
Rejected - Something
how can I now use split on this ouput because I would like to get just Something as output
I tried:
<#list "${reasonValue}"?split("-") as sValue>
${sValue}
</#list>
but problem is that instead of real value i get name of ftl file...
Assign output of include to some variable and then use split on this variable.
<#assign xx>
<#include reasonValue>
</#assign>
<#list xx?split("-") as sValue>
${sValue}
</#list>
If you need to show only part of the string after "-" then use substring and index_of.
${xx?substring(xx?index_of("-") + 2)}

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

Filtering list of beans with expression

I have a list of beans and I would like to get a sub list matching a criteria on one or several properties with an expression as below:
${data[propertyName=='my value']}
data is a list of beans that have a property called propertyName.
Is such approach possible? If not, what is the best approach to do that.
Thanks very much for your answers.
Thierry
You could write a FTL function which selects the list items that match your criteria and collect them in a new sequence via sequence concatenation. Your filter function can be very simple or very sophisticated, it depends on your actual use case. Here is an example how it might work:
<#function filter things name value>
<#local result = []>
<#list things as thing>
<#if thing[name] == value>
<#local result = result + [thing]>
</#if>
</#list>
<#return result>
</#function>
<#-- some test data -->
<#assign data = [ {"propertyName":"my value", "foo":150},
{"propertyName":"other value", "foo":250},
{"propertyName":"my value", "foo":120}] >
<#assign filteredData = filter(data, "propertyName", "my value") >
<#list filteredData as item>
${item.foo}
</#list>
But keep into account that using sequence concatenation might be "suboptimal" for your performance.
You could do it by creating your own filter method variable and exposing it to the template. Then it would just be a matter of calling it with the list of beans and property value you want to filter on:
<#assign filteredData = filter(data, "my value") />
<#list filteredData as item>
// do something fancy
</#list>

Resources