GSoC 2010 – week summary: July 12th – July 18th
Translator
I implemented the Translator class this week. The Translator class is meant to be used for messages’ translation (of course ;-)), and it has pretty interesting functionality. This class is a place where almost all functionality I wrote up to today meets.
First of all, the Translator has two modes of operation: translating by original label, and by ID.
- by original label – searching for translated label is done for original (untranslated) label
- by ID – searching is done for particular identification key
These modes seem to be very similar (as original label and ID are just used as a key), but there is an important difference between them. In general, placing untranslated labels in view templates is more readable (for example, “You should log in before doing this action” is better than “user.notLoggedIn“). But using IDs is probably more maintainable. So the Translator has API for both modes, but whether they are both supported depends on translation provider class used by Translator.
The translation provider is a class which implements TranslationProviderInterface (described in previous summary). Concrete provider doesn’t have to support two modes. The default provider, XliffTranslationProvider, supports both modes as either source labels and IDs are stored in XLIFF files.
Translator requires a $source parameter to be set for every use of translate*() methods. Source is a string identifier understandable by translation provider which uniquely denotes a source catalog of translation labels to use. For XliffTranslationProvider, it’s just a name of XLIFF file.
I think that source parameter should be optional, set by default to “main” for example, as defining it for every method call is pretty redundant. This needs to be discussed by core devs though.
Translator supports plural forms. In order to use them, you need to set the $quantity parameter. It is a number (integer or float, unsigned) used for evaluating a plural-form expression defined for particular language. Of course, the source label has to be translated into all plural forms used in the target language.
It is also worth to note, that when plural forms are used together with the “by original label” translation mode, you need to use singular form for source message. It will be translated to correct plural form if feasible. Please note that it is a subject to change as for example avoiding translation (when source and target language are the same) is not done yet.
The Translator class also uses the FormatResolver for substituting placeholders with formatted values. So you can define a placeholder (like {0,number}) and provide array of values, and they will be formatted and inserted into translated label.
TranslateViewHelper
I also committed preliminary version of the TranslateViewHelper, a view helper for Fluid templating system. It is kind of a wrapper for Translator class, and is also subject to change. Some usage examples:
<f:translate mode="originalLabel" source="main">Untranslated label</f:translate>
<f:translate mode="originalLabel" source="someLabelsCatalog" locale="de_DE">Untranslated label</f:translate>
<f:translate mode="originalLabel" source="main" values="{0: 'foo', 1: '99.9'}">Untranslated {0} and {1,number}</f:translate>
<f:translate mode="id" source="main">user.unregistered</f:translate>
Other
Robert decided to rename the Locale subpackage I’m working on to I18n, as it is better name for the functionality it will provide. So I did it, breaking things in other subpackages by the way :-). Fortunately Karsten was near and fixed all of them.
I also fixed few bugs Bastian noticed, providing me good advices. Thank you!
By the end of this week I was thinking about the next task, a locale-aware input parser for date/time and for numbers. This is my goal for next two weeks, and I hope I will be able to provide a nice solution. Parsing user input can be very hard task. I read about Lenient Parsing. There will probably be few modes of operation, eg. “strict” and “loose”. We will see ;-).