Number Format (Delimiters, Separators...)?

864 views
Skip to first unread message

Johannes Fahrenkrug

unread,
Jul 21, 2008, 4:12:01 AM7/21/08
to rails-i18n
Hi,

this is great news, thanks for all the efforts, guys!
I have just skimmed through some of the posts and api drafts and I
apologize in advance if I missed the answer to my question in one of
those posts.
How will number formatting be supported?

In en-US you'd say 1,000.99 but in de-DE you'd say 1.000,99
Will that be supported? Will there be support for users to enter
values like that? At the moment I use the simple localization plugin
for that and I have to use "price_localized" in my forms in order to
enable my users to enter numbers with the German separators which
works pretty nicely, but setting the number format somewhere and then
not having to worry about it anymore (read: to use "price" instead of
"price_localized" in my forms) would be even nicer of course.

Cheers,

Johannes

--
http://blog.springenwerk.com

Sven Fuchs

unread,
Jul 21, 2008, 7:20:20 AM7/21/08
to rails...@googlegroups.com
Hi Johannes,

welcome to the list!

On 21.07.2008, at 10:12, Johannes Fahrenkrug wrote:
> I have just skimmed through some of the posts and api drafts and I
> apologize in advance if I missed the answer to my question in one of
> those posts.
> How will number formatting be supported?
>
> In en-US you'd say 1,000.99 but in de-DE you'd say 1.000,99
> Will that be supported? Will there be support for users to enter
> values like that? At the moment I use the simple localization plugin
> for that and I have to use "price_localized" in my forms in order to
> enable my users to enter numbers with the German separators which
> works pretty nicely, but setting the number format somewhere and then
> not having to worry about it anymore (read: to use "price" instead of
> "price_localized" in my forms) would be even nicer of course.

If you look at the number_helper #number_to_currency there's quite
some stuff about currency formatting. Can you use that for your forms?

I agree that transparent formatting for form in/output would be nice.
That might be a goal for a plugin to experiment with first though.

WDYT?


--
sven fuchs sven...@artweb-design.de
artweb design http://www.artweb-design.de
grünberger 65 + 49 (0) 30 - 47 98 69 96 (phone)
d-10245 berlin + 49 (0) 171 - 35 20 38 4 (mobile)

Johannes Fahrenkrug

unread,
Jul 21, 2008, 8:06:11 AM7/21/08
to rails-i18n
Hey Sven,

Thank you for the warm welcome :)


> If you look at the number_helper #number_to_currency there's quite  
> some stuff about currency formatting. Can you use that for your forms?

Well, yes and no. Of course you want to "bind" your form elements to a
member. For output these helpers are fine, but not for input.
Simple localization does provide this for me, but simply binding my
input fields to "price_localized": that formats the number to be
1.000,99 but also accepts 7.456,87 as a valid input and converts it so
that the price member of my model will be 7456.87 internally
afterwards.

>
> I agree that transparent formatting for form in/output would be nice.  
> That might be a goal for a plugin to experiment with first though.
>
> WDYT?

Yeah, that makes sense. I'll see that I hit up the simple-localization
guys to maybe join the discussion.

- Johannes

--
http://blog.springenwerk.com

>
> --
> sven fuchs                      svenfu...@artweb-design.de

Sam Lown

unread,
Jul 22, 2008, 2:19:22 PM7/22/08
to rails-i18n
Hi Guys,

I can see this as being something fairly fundamental and easy to get
confused with if not dealt with automatically in some form.

Would it be possible to override the default String#to_f and
Float#to_s (and same for Integer) methods to automatically convert the
number as appropriate for the current locale if available?

Cheers, sam

On Jul 21, 2:06 pm, Johannes Fahrenkrug <jfahrenk...@gmail.com> wrote:
> Hey Sven,
>
> Thank you for the warm welcome :)
>
> > If you look at the number_helper #number_to_currency there's quite  
> > some stuff about currency formatting. Can you use that for your forms?
>
> Well, yes and no. Of course you want to "bind" your form elements to a
> member. For output these helpers are fine, but not for input.
> Simple localization does provide this for me, but simply binding my
> input fields to "price_localized": that formats the number to be
> 1.000,99 but also accepts 7.456,87 as a valid input and converts it so
> that the price member of my model will be 7456.87 internally
> afterwards.
>
>
>
> > I agree that transparent formatting for form in/output would be nice.  
> > That might be a goal for a plugin to experiment with first though.
>
> > WDYT?
>
> Yeah, that makes sense. I'll see that I hit up the simple-localization
> guys to maybe join the discussion.
>
> - Johannes
>
> --http://blog.springenwerk.com

Peter De Berdt

unread,
Jul 22, 2008, 5:46:04 PM7/22/08
to rails-i18n
> I can see this as being something fairly fundamental and easy to get
> confused with if  not dealt with automatically in some form.
>
> Would it be possible to override the default String#to_f and
> Float#to_s (and same for Integer) methods to automatically convert the
> number as appropriate for the current locale if available?

No it doesn't work. The problem is that rails handles numbers in
different ways all over the place. For the input fields for example,
it will just fill in the value before typecast (so the pure database
value). I've tried a number of ways and it's close to impossible to
cleanly cover all bases. The best thing I ended up with, was just
aliassing all number based setters and getters and making methods to
replace them (replacing comma with dot and passing it on to the
original method), all dynamically of course. But in the end, it just
doesn't feel right at all.

Samuel Lown

unread,
Jul 22, 2008, 7:14:27 PM7/22/08
to rails...@googlegroups.com
Peter,

Ah, I had feeling that could be the case, but its interesting to see
that you tried various alternatives there.

It would still be nice to have some kind of solution for modifying
attributes without having to do some kind of conversion before and
after so that handling the params hash is easier. Perhaps something
can be added to ActiveRecord alone just to recognise and convert
attributes being set? I'm not talking full support, but at least some
hooks for a future plugin to handle it more easily perhaps? I've not
studied this part of ActiveRecord enough to know if this is practical.

Cheers, sam

--
www.planetaki.com/sam

Johannes Fahrenkrug

unread,
Jul 24, 2008, 1:07:24 AM7/24/08
to rails-i18n
Hi,

like I wrote before, the simple localization plugin (http://simple-
localization.arkanis.de/) does this already:
they use method_missing so you can use somenumber_localized to get a
localized formatted version of the number and also
somenumber_localized= to set it (Example: in the de-DE locale calling
somenumber_localized="1.099,55" will set the "somenumber" attribute of
your model to 1099.55).
So it is possible.

Stephan Soller

unread,
Jul 24, 2008, 8:17:09 AM7/24/08
to rails...@googlegroups.com
Regarding the localized model attributes feature of Simple Localization:
it was written by Moritz Heidkamp (datenhobel at googlemail dot com) and
uses the attribute_method_suffix method of ActiveRecord. It's not much
code since it uses already localized helpers and strptime for date/time
parsing. Take a look here:
http://svn.arkanis.de/projects/rails_plugins/simple_localization/trunk/simple_localization/lib/features/localized_model_attributes.rb

However I wouldn't include it into Rails right now. Before that more
plugins should experiment with something like this. Maybe there's a more
transparent way of localizing attributes.

ps.: Because of an absolute and unfortunate lack of time I had to stop
development on the Simple Localization project. So don't expect movement
from there any longer. Sorry for that but maybe some other plugin
authors find some ideas useful.


Happy programming

Stephan Soller


Johannes Fahrenkrug schrieb:

Peter De Berdt

unread,
Jul 24, 2008, 6:34:50 PM7/24/08
to rails-i18n
> like I wrote before, the simple localization plugin (http://simple-
> localization.arkanis.de/) does this already:
> they use method_missing so you can use somenumber_localized to get a
> localized formatted version of the number and also
> somenumber_localized= to set it (Example: in the de-DE locale calling
> somenumber_localized="1.099,55" will set the "somenumber" attribute of
> your model to 1099.55).

That was the first way we implemented it. The problem with
method_missing is that it's slow. It was still back in the Rails 1.1.6
days and the performance of our application suffered from it. It's
also quite annoying having to use a suffix in one case and non in your
model or controller for example. That's what i meant by: every
solution is hacky and doesn't feel right. If you wanted to do it right
and make it transparent, it would involve patching quite a bit of
ActiveRecord itself.

Peter De Berdt

unread,
Jul 24, 2008, 6:36:08 PM7/24/08
to rails-i18n
Still, your plugin outshines the rest that's out there, thanks for all
the effort you put in!

On Jul 24, 2:17 pm, Stephan Soller <stephan.sol...@helionweb.de>
wrote:
> Regarding the localized model attributes feature of Simple Localization:
> it was written by Moritz Heidkamp (datenhobel at googlemail dot com) and
> uses the attribute_method_suffix method of ActiveRecord. It's not much
> code since it uses already localized helpers and strptime for date/time
> parsing. Take a look here:http://svn.arkanis.de/projects/rails_plugins/simple_localization/trun...

Julian Tarkhanov

unread,
Jul 25, 2008, 12:37:54 PM7/25/08
to rails...@googlegroups.com

On 25 jul 2008, at 00:36, Peter De Berdt wrote:
> Still, your plugin outshines the rest that's out there, thanks for all
> the effort you put in!

This might sound weird at first, but isn't it a better idea to use
formatter and request middleware for this? (as opposed to doing
conversions on the model level)

Samuel Lown

unread,
Jul 25, 2008, 1:00:58 PM7/25/08
to rails...@googlegroups.com
On Fri, Jul 25, 2008 at 6:37 PM, Julian Tarkhanov
<julian.t...@gmail.com> wrote:
>
> This might sound weird at first, but isn't it a better idea to use
> formatter and request middleware for this? (as opposed to doing
> conversions on the model level)

The point is (as I see it) for the conversion to be done transparently
at least on incoming numbers set using the attributes methods (eg.
update_attributes) so that an incoming parameters don't need to be
handled separetly. The norm in my experience is to pass the params
hash direct to the model where things like time and dates are already
handled and converted automatically, so why not numbers too?

Output is not something I would be so worried about as formatter
methods can be used there, Time#to_s( format ) again is a good example
of this.

Cheers, sam


--
www.planetaki.com/sam

Fjan

unread,
Jul 26, 2008, 5:43:03 AM7/26/08
to rails-i18n
One additional point to add to the discussion:

There are occasions when it is useful to have numbers with a comma
instead of a dot but without thousands separators.
- If you output numbers to a localized version of Excel it will not
accept thousands separators or dots
- Some bank APIs have this as a requirement
- I'm told in France this is actually the preferred way to format
numbers (can someone confirm?)

Of course, this can also be solved with a gsub('.',',') in the
accessors but perhaps we can think of a way to put this transparently
in rails.
Cheers,
jan

Sven Fuchs

unread,
Jul 26, 2008, 7:31:37 AM7/26/08
to rails...@googlegroups.com
Hey guys,

this is really an interesting discussion.

To me actually both layers make sense.

As for the ActiveRecord layer: Josh and I have been mulling about
adding a locale attribute to ActiveRecord models (or even ActiveModel
models) for the Globalize 2 rewrite. That way you could:

a = Article. new :title => 'the default language translation'
a.locale = 'de-DE'
a.title # yields the German translation of #title

I guess it would make sense to wrap all date-, time-, number-related
in a way so that they'd expect input in a format that matches the
current locale that's set on the model. And obviously output data also
formatted in the current locale's default format for that value.

p = Product.new
p.locale = 'de-DE'
p.price = '1.234,56'
p.locale = 'en-US'
p.price # => 1234.56

OTOH I've always been wondering why Rails does not provide the notion
of a Form object which can be used both for outputting form fields
*and* parsing posted params data to create a corresponding model
instance.

# in the products/new view
f = Form.new :for => Product.new(:price => 1234.56), :locale => 'de-DE'
f.input_field :price # => <input ... value="1.234,56">

# in the products/create action
f = Form.new :for => Product.new, :locale => 'de-DE'
f.instantiate :product

Just mulling ...
--
sven fuchs sven...@artweb-design.de

iain

unread,
Jul 30, 2008, 5:49:52 PM7/30/08
to rails-i18n
On Jul 26, 11:43 am, Fjan <jmfa...@gmail.com> wrote:
> Of course, this can also be solved with a gsub('.',',') in the
> accessors but perhaps we can think of a way to put this transparently
> in rails.
> Cheers,
> jan

I don't think ActiveRecord accessors are going to do the trick,
because the numbers have already been typecast. It would already
failed because the String.to_f would typecast it wrong. I'm not sure
if what I'm saying is correct though. I also believe to have read
about a hook in rails to do something before typecasting. Also not
sure about that.

On Jul 26, 1:31 pm, Sven Fuchs <svenfu...@artweb-design.de> wrote:
> As for the ActiveRecord layer: Josh and I have been mulling about  
> adding a locale attribute to ActiveRecord models (or even ActiveModel  
> models) for the Globalize 2 rewrite. That way you could:
>
> a = Article. new :title => 'the default language translation'
> a.locale = 'de-DE'
> a.title # yields the German translation of #title

At first glance, it sounds nasty and over complicated. ;)

> I guess it would make sense to wrap all date-, time-, number-related  
> in a way so that they'd expect input in a format that matches the  
> current locale that's set on the model. And obviously output data also  
> formatted in the current locale's default format for that value.
>
> p = Product.new
> p.locale = 'de-DE'
> p.price = '1.234,56'
> p.locale = 'en-US'
> p.price # => 1234.56

And when p.save is called it should be saved in en-US to the database
of course. I want this to be part of the default rails behaviour if
possible.


> OTOH I've always been wondering why Rails does not provide the notion  
> of a Form object which can be used both for outputting form fields  
> *and* parsing posted params data to create a corresponding model  
> instance.
>
> # in the products/new view
> f = Form.new :for => Product.new(:price => 1234.56), :locale => 'de-DE'
> f.input_field :price # => <input ... value="1.234,56">
>
> # in the products/create action
> f = Form.new :for => Product.new, :locale => 'de-DE'
> f.instantiate :product
>
> Just mulling ...


It does this, right? When you make a block. I don't see the reason why
you want to let the form know which locale it's in though, it can
fetch that from the I18n class. I've been working on a plugin to turn
fields into blocks as well, but I can't decide on the syntax and the
complexity. This is a whole other discussion anyway.

Clemens Kofler

unread,
Jul 30, 2008, 5:50:12 PM7/30/08
to rails-i18n
Johannes,

you might be interested in my big NumberHelper patch that has been
signed off today. It basically adds l10n functionality to *all* helper
methods (not only number_to_currency). Plus, with the change I made to
the structure of the locale file (see here:
http://github.com/rails/rails/tree/master/actionpack/lib/action_view/locale/en-US.rb)
the implementation of l10n user input should be a *lot* easier. So
until Sven and the team have come up with Globalize 2, it should be
feasible to hack your own solution. :-)

Joshua Harvey

unread,
Jul 30, 2008, 6:41:18 PM7/30/08
to rails...@googlegroups.com
Wow, Clemens, this looks awesome. Kudos for taking the i18n code into account -- this is really exciting.

-- Josh
Reply all
Reply to author
Forward
0 new messages