Hi all,
Sorry for my delayed response (I was feeling a bit under the weather).
I'm very happy that our patch is receiving this kind of attention as
it shows that a lot of people are seriously interested in i18n hooks
appearing in rails core.
Also the main reason we decided to add the patch (in it's current
state) was to generate just exactly this kind of discussion which is
great as this is exactly what is happening. Whatever api eventually
does get in to rails core, it should be one that has the blessing of
all developers directly involved in i18n rails development.
Here are my views on what has been said (I'm including things
mentioned in trac)
- In the current patch, the translation method has been added to
String, Date, DateTime & Time.
- The reason we decided to use String#t rather than String#translate
was mainly one of convenience and readability. As this method will
need to be added to many fixed strings throughout the rails core
codebase we opted for something short and sweet which wouldn't add to
much baggage to the rails code itself. I think that String#t can
quickly become a symbol that every rails developer associates with
translation. Saying that I'm not really bothered either way. A
String#translate method (with aliasing as required) would also be
acceptable to me but I think we should get a consensus on this between
all interested parties. I don't think the api itself should do any
aliasing. i.e. If the hook method is translate, any aliasing should be
done by the api implementors and the rails core code itself should use
the unaliased method.
- The issue of pluralization is a tricky one. In order for a string to
be translatable the entire string needs to be passed to String#t.
i.e. consider the following (from action_view/helpers/
active_record_helper.rb):
#134 header_message = "#{pluralize(count, 'error')} prohibited this
#{(options[:object_name] || params.first).to_s.gsub('_', ' ')} from
being saved"
There are two ways of ensuring that this string is translatable:
1. header_message = "#{pluralize(count, 'error')} prohibited this
#{(options[:object_name] || params.first).to_s.gsub('_', ' ')} from
being saved".t
2. header_message = "%d errors prohibited this
#{(options[:object_name] || params.first).to_s.gsub('_', ' ')} from
being saved".t(count)
Version 1 just passes the entire string to String#t (noop) and assumes
the api implementer can handle the translation of this string.
Version 2 modifies the string making it clear that the string has a
plural that has a dynamic value making it easy for api implementers
to handle the pluralization of this string in other languages. Yes,
this isn't a noop but it's of very little cost and provides a
significant advantage over version 1.
- Simple strings that don't require pluralization, in the this patch,
are just returned as is (i.e. noop)
- The patch currently provides for simple/multiple interpolation
(again another non-noop) but this by no means is required to be done
by the String#t method for any string, rather it's mainly used when a
string has a plural and avoiding the noop is not possible.
- The issue of namespacing is again another topic that is best to be
discussed about up front which is partly the reason why we introduced
the assumption in the patch. Namespacing of translatable strings has
many obvious advantages. But it seems to me that a big win for them is
their use in exactly the situation we're in. i.e. Making fixed strings
in a framework translatable. It seems logical to me, that all fixed
strings in rails core be automatically (and silently) added to a
particular namespace in order to avoid clashing.
In fact, the default implementation does not even have to physically
add these strings to any particular namespace, it can just be assumed
that for the api all rails core strings should be added to the 'rails'
namespace by any implementors (Thus reducing clutter in rails core).
As far as, the actual syntax for namespaces is concerned, we like
the idea of using a Symbol (or Array of symbols for nested namespaces)
to denote the namespace but again this is definitely open for
discussion. We like the idea of the following mapping of arguments to
String#t:
String -> Interpolated value
Integer -> Plural value
Symbol -> Namespace
But it's true that other i18n implementations use Symbol as the key
for translations so we should agree on some common ground.
IMO, a translatable string is already a key, in the same regard as
using a symbol for this purpose. You can always provide a distinct
'translation' in the language it's written it.
I also think it's beneficial that the API be flexible enough to
allow the use of Strings and/or Symbols as the translation key. Saying
this, I don't see how this clashes with the use of Symbol as an
argument to #t/#translate
As I just mentioned, the handling of namespaces (which I think is an
integral part of any i18n lib) could be left completely up to the
implementor but I think it's a good idea that the api forces a
particular syntax otherwise you end up with lot's of different types
of syntax for namespaces making it less flexible for users when
switching between implementations. Again, let's discuss this further.
- I don't see any particular reason why this API should have to
'purposefully' wait until after rails 2.0 though in fact, I assumed
this to be the case given the lateness of it's appearance and the time
required to get a consensus between interested parties and a clean
usable patch against the entire rails codebase.
But I do think this is something to be pushed along as quickly as
possible to perhaps make it in for an inevitable 2.0.x rails release.
Josh and I, will certainly be promoting this.
Just to reiterate that this patch is meant for people to play with and
discuss over and NOT as a proposed real patch. i.e. We don't consider
it by no means +1able yet.
Finally, let me add my voice to the call for other prominent i18n/core
rails developers to voice their opinions on this issue so we can get
to a consensus as soon as possible.
Regards,
Saimon