Parameterizing a freemarker builtin - freemarker

Can the builtin part of a expression in freemarker be parameterized?
If so, how?
For example, a date can be formatted with the following builtins:
${openingTime?string.short}
${openingTime?string.medium}
${openingTime?string.long}
${openingTime?string.full}
Can the string.short/string.medium/... builtin names be parameterized too?
For example, I'd like to do something like:
${openingTime?${mydatefmt}}
where mydatefmt is 'string.short' or any valid format.
That would make it easily possible to change the date formats on a freemarker page.
I want to limit the change to a page/file and not apply globally.
Does something like this need to be put into a Freemarker macro that might anticipate all possible types of date formats that might be needed?

One approach is using openingTime?string(pattern), where pattern can be any kind of expression that evaluates to a string. But it's quite verbose and somewhat slow, as the patter will be re-parsed again and again.
Another approach is setting the date_format, time_format and datetime_format FreeMarker settings, and then just write ${openingTime}. (Actually, if openingTime isn't a javax.sql subclass of java.util.Date, you have to write ${openingTime?datetime}, because the Java API doesn't know the difference date-time, time and date-only, but this is another story.) FreeMarker settings can be set globally (better said, on Configuration-level), on template-level (but you don't do that usually), or on the Environment. See http://freemarker.org/docs/pgui_config_settings.html. The last can be done in FTL too, like with <#setting datetime_format = 'yyyy-MM-dd HH:mm:ss zzzz'>.

You have to specify the formatting pattern explicitly : ${openingTime?string("yyyy-MM-dd HH:mm:ss zzzz")}
The date format can be a expression, for example : ${openingTime?string(mydatefmt)}.

Related

Format currency with dot instead of comma using i18n

We are using java.text.NumberFormat class to format the currency values using the method getInstance(Locale paramLocale). Our issue is when we pass es_CO(Columbia) language code it automatically formats it in value 123,00 instead of 123.00. Is there a way to format with dot instead of comma?
I am using Spring platform(hybris)
Please note due to business reasons it is not possible for me to change the locale.
You can use DecimalFormat to have your own format.
Look at this How can I format a String number to have commas and round?

How to use Nifi expression language to change a date into a folder path?

In nifi, I need to transfer a bunch of json files to HDFS. The json files have a field called "creationDate" which has the date in UNIX format. I need to use the date in there to funnel the file to HDFS directories that are named after dates, like "2019-01-19" "2019-01-20" "2019-01-21" etc.
At first I used an "EvaluateJsonPath" processor going to a "PutHDFS" processor. The "Evaluate..." processor had "creationDate" as the property and "${creationDate} as the value. In the PutHDFS processor, for directory I put "/${creationDate}"
But then I realized that the date in the json file has the full timestamp, like "2019-01-19T04:34:28.527722+00:00
Obviously I don't need all that, just the first eight digits. So how can I turn this big string into a neat 8-digit directory name? Will I need to use a regex, and if so, how can this be implemented? Thanks in advance for any help.
You can use UpdateAttribute and use the date expression language functions to format it.
https://nifi.apache.org/docs/nifi-docs/html/expression-language-guide.html
Example (not specific to your format):
${creationDate:toDate('MM-dd-yyyy'):format('yyyy/MM/dd')}
In UpdateAttribute you would add a new property name creationDate and set the value to an expression like above.

Figure date format from string in ruby

I am working in a simple data loader for text files and would like to add a feature for correctly loading dates into the tables. The problem I have is that I do not know the date format before hand, and it will not be my script doing the inserts - it has to generate insert statements for later use.
The Date.parse is almost what I'd need. If there was a way to grab the format it identified on the string in a way I could use to generate a to_date(...)(Oracle standard) would be perfect.
An example:
My input file:
user_name;birth_date
Sue;20130427
Amy;31/4/1984
Should generate:
insert into my_table values ('Sue', to_date('20130427','yyyymmdd'));
insert into my_table values ('Amy', to_date('31/4/1984','dd/mm/yyyy'));
Note that it is important the original string remains unchanged - so I cannot parse it to a standard format used in the inserts (it is a requirement).
At the moment I am just testing a bunch of regexes and doing some validation, but I was wondering if there was a more robust way.
Suppose (using for example String#scan), you extracted an array of the date strings from a single file. It may be like:
strings = ["20130427", "20130102", ...]
Prepare in advance an array of all formats you can think of. It may be like:
Formats = ["%Y%m%d", "%y%m%d", "%y/%m/%d", "%m/%d/%y", "%d/%m/%y", ...]
Then check all formats that can parse all of the strings:
require "date"
formats =
Formats.select{|format| strings.all?{|s| Date.strptime(s, format) rescue nil}}
If this array formats includes exactly one element, then that means the strings were unambiguously parsed with that format. Using that format, you can go back to the strings and parse them with that format.
Otherwise, either you failed to provide the appropriate format within Formats, or the strings remained ambiguous.
I would use the Chronic gem. It will extract dates in most formats.
It has options to resolve the ambiguity in the xx/xx/xxxx format, but you'd have to specify which to prefer when either match.

How to output ${expression} in FreeMarker that contains HTML AS HTML

In my data model myVar contains <b>hello</b> and when I bring it like this ${myVar} the output I get is literally <b>hello</b> rather than hello.
Any idea how to correct this?
Certainly you have HTML escaping on, so try <#noescape>${myvar}</#noescape>.
Update: Since 2.3.24 a new kind of auto-escaping was introduced, which doesn't use #escape, and hence nor #noescape. When that's used, write ${myvar?no_esc} to avoid escaping. Or, you can put the value into the data-model already as a TemplateHTMLOutputModel (created with HTMLOutputFormat.fromMarkup(myString)), and then FreeMarker will know without ?no_esc that it need not be escaped.

How do you check for a changing value within a string

I am doing some localization testing and I have to test for strings in both English and Japaneses. The English string might be 'Waiting time is {0} minutes.' while the Japanese string might be '待ち時間は{0}分です。' where {0} is a number that can change over the course of a test. Both of these strings are coming from there respective property files. How would I be able to check for the presence of the string as well as the number that can change depending on the test that's running.
I should have added the fact that I'm checking these strings on a web page which will display in the relevant language depending on the location of where they are been viewed. And I'm using watir to verify the text.
You can read elsewhere about various theories of the best way to do testing for proper language conversion.
One typical approach is to replace all hard-coded text matches in your code with constants, and then have a file that sets the constants which can be updated based on the language in use. (I've seen that done by wrapping the require of that file in a case statement based on the language being tested. Another approach is an array or hash for each value, enumerated by a variable with a name like 'language', which lets the tests change the language on the fly. So validations would look something like this
b.div(:id => "wait-time-message).text.should == WAIT_TIME_MESSAGE[language]
To match text where part is expected to change but fall within a predictable pattern, use a regular expression. I'd recommend a little reading about regular expressions in ruby, especially using unicode regular expressions in ruby, as well as some experimenting with a tool like Rubular to test regexes
In the case above a regex such as:
/Waiting time is \d+ minutes./ or /待ち時間は\d+分です。/
would match the messages above and expect one or more digits in the middle (note that it would fail if no digits appear, if you want zero or more digits, then you would need a * in place of the +
Don't check for the literal string. Check for some kind of intermediate form that can be used to render the final string.
Sometimes this is done by specifying a message and any placeholder data, like:
[ :waiting_time_in_minutes, 10 ]
Where that would render out as the appropriate localized text.
An alternative is to treat one of the languages as a template, something that's more limited in flexibility but works most of the time. In that case you could use the English version as the string that's returned and use a helper to render it to the final page.

Resources