Re: [Catalyst] I18N with variables
On 7 Aug 2010, at 01:03, Ton Voon wrote: I can write a Cat advent calendar entry for this if interested. YES! We were happy to take submissions for this years advent as of Jan 1st, so please do so! ;) (Any time before mid december) Cheers t0m ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] I18N with variables
On Mon, 02 Aug 2010 07:08:04 +0200, Julien Sobrier jul...@sobrier.net wrote: Also, writing [% c.loc(foo) %] does not create an entry in messages.po when running xgettext.pl, like [% c.loc('foo') %] does. To make that work, I think you'd have to actually *run* your templates for all possible cases, and then collect all the strings that were passed as arguments to c.loc(). In other words, I'm not saying it's impossible, but xgettext.pl will probably never be able to do that. A slightly different approach, that works for me, is to create your .PO files in different stages. First step parses the templates with xgettext.pl and generates the .PO files. A second step can, for example, parse the actual source code, for stuff like '$c-loc(foo)'. xgettext.pl can do that with a bit of trickery. The new messages will be merged together in the same .PO files. In your case, you could pull the messages you want to be translated directly from the database, and write some on-the-fly fake templates (or text files for that matter), and feed them to xgettext.pl. -- Cosimo ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] I18N with variables
I've more or less given up on it, mostly because there are a few use cases where text needs translated that's not easily passed through c-loc, for example dynamically generated descriptions and such things. They *could* be put through c-loc but that ties some logic too tight to the whole web app for it to be worthwhile. One thing I tend to do is just separate things to a ridiculous degree; instead of going [% c.loc('hi there') %], I'll in fact name it [% c.loc('index_tt2_hi_there') %] - which means that I need to translate for en_us as well (or at least put the text in). Inside perl modules, text that needs translated (e.g. modules that aren't tied to Catalyst), they all use another module I wrote that makes you register all different text identifiers, and will cache them; if you don't register it, you can't use it (error shows up), and once it's registered, another script will yank the cached entries and will merge them into an existing .po file if they need to be there. There's also the issue that I'm dealing with now where I have a web shop that I need to build that needs to be fully bilingual. Including product descriptions and names - this makes things interesting because I18N is absolutely useless for it, so I'm building a set of modules that attempt to solve the whole problem gracefully; perhaps something to stick on CPAN at some point. Cosimo Streppone wrote: On Mon, 02 Aug 2010 07:08:04 +0200, Julien Sobrier jul...@sobrier.net wrote: Also, writing [% c.loc(foo) %] does not create an entry in messages.po when running xgettext.pl, like [% c.loc('foo') %] does. To make that work, I think you'd have to actually *run* your templates for all possible cases, and then collect all the strings that were passed as arguments to c.loc(). In other words, I'm not saying it's impossible, but xgettext.pl will probably never be able to do that. A slightly different approach, that works for me, is to create your .PO files in different stages. First step parses the templates with xgettext.pl and generates the .PO files. A second step can, for example, parse the actual source code, for stuff like '$c-loc(foo)'. xgettext.pl can do that with a bit of trickery. The new messages will be merged together in the same .PO files. In your case, you could pull the messages you want to be translated directly from the database, and write some on-the-fly fake templates (or text files for that matter), and feed them to xgettext.pl. -- Ben van Staveren phone: +62 81 70777529 email: benvanstave...@gmail.com ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] I18N with variables
Hi, Am 06.08.2010 um 14:58 schrieb Ben van Staveren: There's also the issue that I'm dealing with now where I have a web shop that I need to build that needs to be fully bilingual. Including product descriptions and names - this makes things interesting because I18N is absolutely useless for it, so I'm building a set of modules that attempt to solve the whole problem gracefully; perhaps something to stick on CPAN at some point. I'm using short identifiers for my I18N texts, like Home.Greeting which is then translated to Hi there for en_us or Hallöchen for de_de. When I added a small CMS to a customer's application all texts should also be translated. So I saved any text to I18N key CMS.NavigationPoint.PageKey.* within the right language file (actually I'm using C::P::I18N::DBI), * for Title or Content or similar. I think it should be possible to handle product descriptions like this. In your Backend save every text to Product.$ArticleNumber.Description, Product.$ArticleNumber.Name, Product.$ArticleNumber.Variant and so on where $ArticleNumber is the actual article number. The possible languages should be somewhere in your Catalyst config. Matthias -- rainboxx Software Engineering Matthias Dietrich rainboxx Matthias Dietrich | Phone: +49 7141 / 2 39 14 71 Königsallee 43 | Fax : +49 3222 / 1 47 63 00 71638 Ludwigsburg| Mobil: +49 151 / 50 60 78 64 | WWW : http://www.rainboxx.de CPAN: http://search.cpan.org/~mdietrich/ XING: https://www.xing.com/profile/Matthias_Dietrich18 GULP: http://www.gulp.de/profil/rainboxx.html ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] I18N with variables
Hi Matthias, That's what I considered at some point, but what happens there is that you are more or less totally working around the I18N module at that point. I did some experimenting with a subclass of TT that was actually translation aware and would do it on a much lower level (given that I use TT for the web-facing end of the app, as well as for emails, generated files on disk, and even use it to an extend to generate shipping labels). Matthias Dietrich wrote: Hi, Am 06.08.2010 um 14:58 schrieb Ben van Staveren: There's also the issue that I'm dealing with now where I have a web shop that I need to build that needs to be fully bilingual. Including product descriptions and names - this makes things interesting because I18N is absolutely useless for it, so I'm building a set of modules that attempt to solve the whole problem gracefully; perhaps something to stick on CPAN at some point. I'm using short identifiers for my I18N texts, like Home.Greeting which is then translated to Hi there for en_us or Hallöchen for de_de. When I added a small CMS to a customer's application all texts should also be translated. So I saved any text to I18N key CMS.NavigationPoint.PageKey.* within the right language file (actually I'm using C::P::I18N::DBI), * for Title or Content or similar. I think it should be possible to handle product descriptions like this. In your Backend save every text to Product.$ArticleNumber.Description, Product.$ArticleNumber.Name, Product.$ArticleNumber.Variant and so on where $ArticleNumber is the actual article number. The possible languages should be somewhere in your Catalyst config. Matthias -- Ben van Staveren phone: +62 81 70777529 email: benvanstave...@gmail.com ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] I18N with variables
On Fri, Aug 6, 2010 at 6:16 AM, Matthias Dietrich mdietr...@cpan.orgwrote: I'm using short identifiers for my I18N texts, like Home.Greeting which is then translated to Hi there for en_us or Hallöchen for de_de. When I added a small CMS to a customer's application all texts should also be translated. So I saved any text to I18N key CMS.NavigationPoint.PageKey.* within the right language file (actually I'm using C::P::I18N::DBI), * for Title or Content or similar. I've been arguing with work about how to key our text. So far we continue to use the English in the loc() tags in the templates, and then the I18N team uses a script to pull out this text which gets sent to translation services. The risk is text gets into the templates that for some reason does not get pulled out. The developers like the English in the templates as it makes them easy to read, and it means they don't really have to stop when entering new text. Just seems like in the long run this will be unmaintainable and error prone. (Well, not in the long run as it already is error prone.) I've been arguing for a system where we use some kind of ID for the keys. I'm not so sure the key format matters -- could be just a primary key in the db, for example. This could be a stage done by the designers so the design spec just indicates a message id. Then code development and translation can happen at the same time. Is anyone using a system like that? And more specifically, what application are you using to manage the translation database? We have started to write one, but it's a bit more than trivial as we need it to work with different translation services, track history/changes, multiple applications, etc. So, it would make more sense to use an existing tool. So, I'd like to hear about your translation workflow and any tools you are using. Thanks, -- Bill Moseley mose...@hank.org ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] I18N with variables
On Fri, 06 Aug 2010 16:57:42 +0200, Bill Moseley mose...@hank.org wrote: I've been arguing with work about how to key our text. So far we continue to use the English in the loc() tags in the templates, and then the I18N team uses a script to pull out this text which gets sent to translation services. We also chose to use english text as message keys. I wanted to avoid ids because: 1) Retrofitting i18n in an existing app would make you spend weeks/months replacing all the text messages with ids. 2) Designers or front-end developers work suddenly becomes much harder. You need to provide them a database of already used IDs and what they mean. 3) With IDs it's difficult to identify when a message has arguments, and which ones, or even how many of them: Hello, [_1], you have [_quant,_2,message,messages,no messages] The main disadvantage I see is that when you change your text, all the .PO files need to be updated, so you actually kill some of the existing messages, and you have to manage that with your i18n tools. So, I'd like to hear about your translation workflow and any tools you are using. I found the latest Transifex (0.9.0+) very good for us: http://trac.transifex.org/ We're managing our own instance. Pay attention if you plan to do that: http://my.opera.com/cstrep/blog/2010/06/22/dependencies-suck -- Cosimo ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] I18N with variables
Hi Bill, Back in the day (heh) we faced the same problem for an app we were doing for a client, because the client insisted they wanted the ability to do their own translations, we ended up with text keyed on the location where it was called from, and the actual english string. So in a template we'd get index.tt2(hello there, customer) as the key, but inside the template it was generated by doing [% f.xlat(hello there, customer) %] - or if you wanted parameters it was more like [% f.xlat(hello there, %, array_of_data) %]. We used one script that would just walk the template directory, and would set up the stash like this: $stash = { f = { xlat = sub { my $string = shift; my @params = (@_); ... }, }, }; We'd run it, and based on filename and the actual string passed it'd generate the master key file - some more scripts would look at duplicates (e.g. if more than one template contained the same string) and would generate a yaml configuration file containing a string = template mapping. Similarly, inside perl modules we used the same mechanism, also described this in an earlier reply; where all translation strings *had* to be registered during module initialisation and it would then dump these to it's own master key file. Rinse, repeat, merge. This then ended up going through the actual application's admin interface into the database, where it'd also flag everything that required translation into the available languages, so that the clients' translator team could go and take care of it. In the end probably not the most graceful of solutions, and error-wise there were a few where certain phrases could have different meanings based on context but the code couldn't determine that - but usually that got fixed with a little rephrasing in choice locations :) That's also the system I'm currently using in a slightly modified form for the webshop I'm building at the moment. I'll see if I can roll it all up into something distributable and put it online for download but that will have to happen some time later. Bill Moseley wrote: On Fri, Aug 6, 2010 at 6:16 AM, Matthias Dietrich mdietr...@cpan.org mailto:mdietr...@cpan.org wrote: I'm using short identifiers for my I18N texts, like Home.Greeting which is then translated to Hi there for en_us or Hallöchen for de_de. When I added a small CMS to a customer's application all texts should also be translated. So I saved any text to I18N key CMS.NavigationPoint.PageKey.* within the right language file (actually I'm using C::P::I18N::DBI), * for Title or Content or similar. I've been arguing with work about how to key our text. So far we continue to use the English in the loc() tags in the templates, and then the I18N team uses a script to pull out this text which gets sent to translation services. The risk is text gets into the templates that for some reason does not get pulled out. The developers like the English in the templates as it makes them easy to read, and it means they don't really have to stop when entering new text. Just seems like in the long run this will be unmaintainable and error prone. (Well, not in the long run as it already is error prone.) I've been arguing for a system where we use some kind of ID for the keys. I'm not so sure the key format matters -- could be just a primary key in the db, for example. This could be a stage done by the designers so the design spec just indicates a message id. Then code development and translation can happen at the same time. Is anyone using a system like that? And more specifically, what application are you using to manage the translation database? We have started to write one, but it's a bit more than trivial as we need it to work with different translation services, track history/changes, multiple applications, etc. So, it would make more sense to use an existing tool. So, I'd like to hear about your translation workflow and any tools you are using. Thanks, -- Bill Moseley mose...@hank.org mailto:mose...@hank.org ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/ -- Ben van Staveren phone: +62 81 70777529 email: benvanstave...@gmail.com ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] I18N with variables
Hi Bill, Am 06.08.2010 um 16:57 schrieb Bill Moseley: I've been arguing with work about how to key our text. So far we continue to use the English in the loc() tags in the templates, and then the I18N team uses a script to pull out this text which gets sent to translation services. The risk is text gets into the templates that for some reason does not get pulled out. yes, that's an issue with my solution, too. You code and add texts and if you don't add them immediately to the database you may get lost. Especially when you have code with I18N text that only gets called in some special circumstances that you can hardly simulate, so your text stays as a key (or english text) until someone stumbles upon this special case and reports. I've been arguing for a system where we use some kind of ID for the keys. I'm not so sure the key format matters -- could be just a primary key in the db, for example. This could be a stage done by the designers so the design spec just indicates a message id. Then code development and translation can happen at the same time. Using an integer ID doesn't sound useful to me. An ID doesn't say anything about what it should be replaced with, a key does (should). My keys also have arguments like Home.Greeting[_1] which could be translated to Hello [_1]. A disadvantage of using english as identifier is: when you change the text, say you have a typo in it, you need to change all you translations so they have the correct identifier again. If you have a key (or integer ID), changing the typo is easy because there is a additional translation and typos in your keys are irrelevant. So, I'd like to hear about your translation workflow and any tools you are using. My tools were pgAdmin3 and some AutoCRUD until now, because there has not been any big translation. In a project at my former employer we wrote a small Excel import script because the customer translated every text with Excel. There's no magic here that could help you, sorry. Thanks, Matthias -- rainboxx Software Engineering Matthias Dietrich rainboxx Matthias Dietrich | Phone: +49 7141 / 2 39 14 71 Königsallee 43 | Fax : +49 3222 / 1 47 63 00 71638 Ludwigsburg| Mobil: +49 151 / 50 60 78 64 | WWW : http://www.rainboxx.de CPAN: http://search.cpan.org/~mdietrich/ XING: https://www.xing.com/profile/Matthias_Dietrich18 GULP: http://www.gulp.de/profil/rainboxx.html ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] I18N with variables
On 6 Aug 2010, at 15:57, Bill Moseley wrote: I've been arguing with work about how to key our text. So far we continue to use the English in the loc() tags in the templates, and then the I18N team uses a script to pull out this text which gets sent to translation services. For Opsview (http://opsview.com), we decided early on to use message ids. I'm very glad of this decision (after pain in my work on the Nagios Plugins using English text as the key). After chatting to a Java guy who already implemented i18n in his app, we went with a dotted notation like: [% c.loc(ui.admin.host.edit.label.hostaddress) %] The dotted notation is good because it gives a pretty good idea where in the app this text will be found. The last part can be as complex as you like to describe the content. Variables work with: [% c.loc(ui.admin.host.edit.label.numberOfAddresses [_1], num_addresses) %] Obviously, there needs to be an English translation. This is when I spent about 10 hours of my life trying to work out how Locale::Maketext::Simple was not doing a fallback as I expected. A patch was made and thankfully this works properly now if you set your .po file to be called i_default.po: http://cpansearch.perl.org/src/JESSE/Locale-Maketext-Simple-0.19/Changes I run a make gettext in my cat app that calls xgettext.pl and some other perl code to check for missing strings in i_default.po. It also updates all our language files with any new msgids but sets msgstr to . This is good because: (1) Locale::Maketext::Simple will now fallback to i_default.po and (2) anyone translating the .po files can easily see which strings still need translating. So overall I think our workflow is pretty good. I can write a Cat advent calendar entry for this if interested. Ton ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] I18N with variables
On 2 Aug 2010, at 06:08, Julien Sobrier wrote: Hello, I've started to translate my website using Catalyst::Plugin::I18N. It works fine for static text. Bu I can't make it work for variables. For example, I need to a translation for [% foo %] where for can take a set of values defined in a database. I'm sot sure what is the best way to translate such variables, and what is possible: * add a msgid for each possible value in messages.po = those gets removed every time I run xgettext.pl * Make the translation in my Database layer = unfortunately I use the old Class::DBI, and could not find a plugin for it * any other option? What I do is use the variable to work out the dynamic name, and then in a dummy template file, have the possible options. Eg: [% menu_name=Configuration; c.loc(menu_name) %] Then in a dummy template file, have: [% c.loc(Configuration) %] This way xgettext.pl will always find it to put into messages.po. It means having to write in the dummy template all the possibilities, but it would have to be captured somewhere, so it might as well be in something that xgettext.pl can process. Ton ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
Re: [Catalyst] I18N with variables
Check out Catalyst::Plugin::Localize::Simple http://search.cpan.org/~wehr/Catalyst-Plugin-Localize-Simple-1.1/lib/Catalyst/Plugin/Localize/Simple.pm I made it to overcome the learning curve of i18n, and it works very well. Used it to translate English to Spanish, French, Japanese, Italian, Portuguese, and Chinese Simplified. I provided a CMS for the translation team to create and modify these translation files. Very simple and straight forward. Let me know if you have questions on usage. -nw On Wed, Aug 4, 2010 at 1:04 AM, Ton Voon ton.v...@opsera.com wrote: On 2 Aug 2010, at 06:08, Julien Sobrier wrote: Hello, I've started to translate my website using Catalyst::Plugin::I18N. It works fine for static text. Bu I can't make it work for variables. For example, I need to a translation for [% foo %] where for can take a set of values defined in a database. I'm sot sure what is the best way to translate such variables, and what is possible: * add a msgid for each possible value in messages.po = those gets removed every time I run xgettext.pl * Make the translation in my Database layer = unfortunately I use the old Class::DBI, and could not find a plugin for it * any other option? What I do is use the variable to work out the dynamic name, and then in a dummy template file, have the possible options. Eg: [% menu_name=Configuration; c.loc(menu_name) %] Then in a dummy template file, have: [% c.loc(Configuration) %] This way xgettext.pl will always find it to put into messages.po. It means having to write in the dummy template all the possibilities, but it would have to be captured somewhere, so it might as well be in something that xgettext.pl can process. Ton ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/ ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/
[Catalyst] I18N with variables
Hello, I've started to translate my website using Catalyst::Plugin::I18N. It works fine for static text. Bu I can't make it work for variables. For example, I need to a translation for [% foo %] where for can take a set of values defined in a database. I'm sot sure what is the best way to translate such variables, and what is possible: * add a msgid for each possible value in messages.po = those gets removed every time I run xgettext.pl * Make the translation in my Database layer = unfortunately I use the old Class::DBI, and could not find a plugin for it * any other option? Also, writing [% c.loc(foo) %] does not create an entry in messages.po when running xgettext.pl, like [% c.loc('foo') %] does. Thanks Julien ___ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/