Re: [Catalyst] I18N with variables

2010-08-09 Thread Tomas Doran


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

2010-08-06 Thread Cosimo Streppone
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

2010-08-06 Thread Ben van Staveren
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

2010-08-06 Thread Matthias Dietrich
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

2010-08-06 Thread Ben van Staveren

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

2010-08-06 Thread Bill Moseley
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

2010-08-06 Thread Cosimo Streppone

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

2010-08-06 Thread Ben van Staveren

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

2010-08-06 Thread Matthias Dietrich
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

2010-08-06 Thread Ton Voon


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

2010-08-04 Thread Ton Voon


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

2010-08-04 Thread Nicholas Wehr
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/