You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@freemarker.apache.org by Eduard Valiauka <ed...@gmail.com> on 2015/10/13 16:38:39 UTC

Number format configuration option

Hello, folks

In our project we are using freemarker to process dynamic(written by users)
templates.
So, our code related to template processing looks like the following:

Configuration configuration = new Configuration();
configuration.setLocale(locale);
new Template("name", template, configuration).process(data, stringWriter);

Our requirements for processing output are
1. Number formatting should be localized
2. Fraction digits should never be cut. That means that 1.12345 should not
be displayed as 1.123. This happens because default value for
NumberFormat#maxFractionDigits is 3

We ended up by setting the following configuration option
conf.setNumberFormat("###,###.####################");

But I personally feel that working with format patterns is a bit
counter-intuitive and error-prone.
I would prefer the following:

NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);
numberFormat.setMaximumFractionDigits(Integer.MAX_VALUE);
configuration.setNumberFormat(numberFormat);

But setNumberFormat only accepts strings.
Looking at the source of freemarker.core.Environment it does not look like
a huge change to provide a method that would accept an instance of
NumberFormat.

Do you guys already have plans for implemenation of this change? I would
really appreciate having this functionality.




Thank you for your time,
Eduard

Re: Number format configuration option

Posted by Daniel Dekany <dd...@freemail.hu>.
There are substantial new features in the upcoming release (2.3.24)
regarding formatting, though their purpose is adding new
functionality, rather than streamlining configuration (which is what
you aim for, if I understand well), which you usually only do once or
so.

If you check out the head (the 2.3-gae or 2.3 branch preferably),
there's something called freemarker.core.TemplateNumberFormat and
freemarker.core.TemplateDateFormat. These are similar in purpose to
Java's NumberFormat and DateFormat, but are specialized for the
requirements of FreeMarker.

But, you can't specify these directly in the configuration. The
numberFormat and dateFormat etc. settings are still strings, because
lot of already existing functionality builds on that (like
foo?string("#.###")), and also because you can't really "overload" a
setting since it has both a setter and a getter side. So there's a
customNumberFormats (of type Map<String, ? extends
TemplateNumberFormatFactory>) and a customDateFormats (of type
Map<String, ? extends TemplateDateFormatFactory>) setting, with which
you can register your own formatters, and then refer to them like
setNumberFormat("@myFormat") or even setNumberFormat("@myFormat some
params that it will parse"). So that's how it goes; a bit of
indirection. This new feature has two main points. One is that now you
can write your own formatters in Java, and you aren't forced to use
DecimalFormat and SimpleDateFormat anymore, which were often limiting.
The other is that you can use application domain format names like
"@price", "@coordinate", etc., and then control outside the templates
how a "price" or a "coordinate" looks. And actually, there's a third
smaller point, that as now the formatter has access to the
TemplateModel, it can decide the format depending on the meaning of
the number, like automatically show units next to it, if you put the
necessary information into your data model. And there's even a fourth
point, that now a formatter can choose to output markup (like HTML)
instead of plain text.

So that's what we have in 2.3.24 now, which I hope will be released
this year. If you can start using it and give feedback, like report
rough edges and bugs, that's a big help.

-- 
Thanks,
 Daniel Dekany


Tuesday, October 13, 2015, 4:38:39 PM, Eduard Valiauka wrote:

> Hello, folks
>
> In our project we are using freemarker to process dynamic(written by users)
> templates.
> So, our code related to template processing looks like the following:
>
> Configuration configuration = new Configuration();
> configuration.setLocale(locale);
> new Template("name", template, configuration).process(data, stringWriter);
>
> Our requirements for processing output are
> 1. Number formatting should be localized
> 2. Fraction digits should never be cut. That means that 1.12345 should not
> be displayed as 1.123. This happens because default value for
> NumberFormat#maxFractionDigits is 3
>
> We ended up by setting the following configuration option
> conf.setNumberFormat("###,###.####################");
>
> But I personally feel that working with format patterns is a bit
> counter-intuitive and error-prone.
> I would prefer the following:
>
> NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);
> numberFormat.setMaximumFractionDigits(Integer.MAX_VALUE);
> configuration.setNumberFormat(numberFormat);
>
> But setNumberFormat only accepts strings.
> Looking at the source of freemarker.core.Environment it does not look like
> a huge change to provide a method that would accept an instance of
> NumberFormat.
>
> Do you guys already have plans for implemenation of this change? I would
> really appreciate having this functionality.
>
>
>
>
> Thank you for your time,
> Eduard