Thread: [htmltmpl] HTML::Template and Locale::Maketext
Brought to you by:
samtregar
From: Johan K. <ku...@re...> - 2005-05-25 17:41:51
|
Hi, This is a long post, so feel free to stop reading now. :-) Anyone has used HTML::Template and Locale::Maketext together? Or HTML::Template in any I18N project? My doubts are mostly what approach I should use. The application I planning to start is not that big, but I always liked=20 separating things: a. .pl files - For the Perl programmer. b. .html files - for the web designer c. .po and/or .pm files containing just languages hashes - for the language= =20 translator (ok, Perl hashes, but very readable even for a non-programmer) To keep things separated, there is a problem: 1. If, on one hand, I want to use one single HTML::Template for the output = in=20 different languages, the template itself cannot have any "fixed strings" in= =20 one languages, but has to be filled up only with <TMPL_VAR NAME=3Dxxx> tags= for=20 every single message. This makes the job tougher for the web designer (the web page preview will = be=20 almost unreadable). 2. If, on the other hand, one HTML::Template per language, the translator h= as=20 to know some HTML to create a HTML::Template with "fixed strings" in her/hi= s=20 language. And this means that the web designer will end up with one templat= e=20 per language, which also is undesirable. Any suggestions are appreciated. I will try explaining details of the problem by using a couple of examples: Approach 1, using one template for all languages: hello.pl # ---------------------------------------- #!/usr/bin/perl -w use HTML::Template; use MyApp:I18N; my $locale =3D $ARGV || 'en'; # Use English as default my $lh =3D MyApp::I18N->get_handle($locale) || die "Can't get a language=20 handle!"; # open the html template my $template =3D HTML::Template->new(filename =3D> 'hello.world.tmpl.html'); # fill in some parameters $template->param( HELLO_WORLD =3D> $lh->maketext("Hello, world!"), WELCOME_TO_THIS_WEB_SITE =3D> $lh->maketext("Welcome to this web site."), ); # send the obligatory Content-Type and print the template output print "Content-Type: text/html\n\n", $template->output; # ---------------------------------------- hello.world.tmpl.html # ---------------------------------------- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title><TMPL_VAR NAME=3DHELLO_WORLD></title> </head> <body> <b><TMPL_VAR NAME=3DHELLO_WORLD></b> <p><TMPL_VAR NAME=3DWELCOME_TO_THIS_WEB_SITE></p> </body> </html> # ---------------------------------------- MyApp/I18N/en.pm # ---------------------------------------- package MyApp::I18N::es; # Spanish language messages use base qw(MyApp::I18N); use strict; use vars qw(%Lexicon); %Lexicon =3D ( # Message to translator: Start here! "Hello, world!" =3D> "Hello, world!", "Welcome to this website." =3D> "Welcome to this website.", # Message to translator: Stop here! ); # ---------------------------------------- MyApp/I18N/es.pm # ---------------------------------------- package MyApp::I18N::es; # Spanish language messages use base qw(MyApp::I18N); use strict; use vars qw(%Lexicon); %Lexicon =3D ( # Mensaje a traductor: =A1Empieza aqu=ED! "Hello, world!" =3D> "=A1Hola, mundo!", "Welcome to this website." =3D> "Bienvenido a este sitio web.", # Mensaje a traductor: =A1Termina aqu=ED! ); # ---------------------------------------- MyApp/I18N/se.pm # ---------------------------------------- package MyApp::I18N::es; # Swedish language messages use base qw(MyApp::I18N); use strict; use vars qw(%Lexicon); %Lexicon =3D ( # Meddelande till =F6vers=E4ttaren: B=F6rja h=E4r! "Hello, world!" =3D> "Hej, v=E4rlden!", "Welcome to this website." =3D> "V=E4lkommen till den h=E4r webbsajten.", # Meddelande till =F6vers=E4ttaren: Sluta h=E4r! ); # ---------------------------------------- Approach 2, using one template per language: hello.pl # ---------------------------------------- #!/usr/bin/perl -w use HTML::Template; my $locale =3D $ARGV || 'en'; # Use English as default my $filename =3D 'hello.world.tmpl.html.' . $locale; # open the html template my $template =3D HTML::Template->new(filename =3D> $filename); # send the obligatory Content-Type and print the template output print "Content-Type: text/html\n\n", $template->output; # ---------------------------------------- hello.world.tmpl.html.en # ---------------------------------------- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title>Hello, world!</title> </head> <body> <b>Hello, world!</b> <p>Welcome to this website.</p> </body> </html> # ---------------------------------------- hello.world.tmpl.html.es # ---------------------------------------- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title>=A1Hola, mundo!</title> </head> <body> <b>=A1Hola, mundo!</b> <p>Bienvenido a este sitio web.</p> </body> </html> # ---------------------------------------- hello.world.tmpl.html.se # ---------------------------------------- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title>Hej, v=E4rlden!</title> </head> <body> <b>Hej, v=E4rlden!</b> <p>V=E4lkommen till den h=E4r webbsajten.</p> </body> </html> # ---------------------------------------- Best Regards, Johan Kuuse |
From: Markus S. <m.s...@gm...> - 2005-05-25 21:28:38
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi Johan, I stood in front of the same problem 2 years ago and came up with a solution that combines (in my eyes) the best of HTML::Template and Locale::Maketext. The principle is as such: The html-code of the template is parsed by HTML::Parser. Strings between tags and certain attribute values (title, alt) are translated by means of Locale::Maketext. A subclass of HTML::Templates caches the different translations through different keys. My solution is by all means not perfect, especially the HTML::Template subclass would much better be rewritten in form of a decent patch (Cees Heek has advised on this, but I never found time to realize this), and therefore was never published. However I put it on a university server where you can download it. Documentation for sure is optimal, but the test scripts explain very clearly the usage. The files are http://dream.lrrl.arch.tu-muenchen.de/~springm/CPAN/authors/id/MSPRING/HTML-Translator-0.03.tar.gz http://dream.lrrl.arch.tu-muenchen.de/~springm/CPAN/authors/id/MSPRING/HTML-I18Template-0.01.tar.gz I would be glad if my solution could be of any usage for you. Kind regards Markus Spring -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iD8DBQFClO4BxxUzQSse11ARAqV/AJsF+8rHcwClEJzF5w19JI+GWhBZgwCfR+sn cO/dmpSc/OBAl449Dfk1EFI= =A4qa -----END PGP SIGNATURE----- |
From: Mathew R. <mat...@re...> - 2005-05-26 10:51:40
|
Hi Johan, About 18 months ago I had a similar requirement, and thus eventually got = around to looking at Locale::Maketext. One of the key points that the = documentation makes, is that English is not a language that you should = derive your second language from. One problem I had with L::M was that = it still forces some of the "English is a base language" syndrome onto = the programmer. I also like the idea of not needing to distribute .po = files for every GUI change. So I created Locale::MakeText. Then I patch H::T so that it is capable of supporting custom TMPL_xxx = tags. Then I wrote a module to combine the two. The end result is that my translations are: - stored in a database (whenever I do do a GUI update, translations can = happen in real-time) - singular/plural aware (and the rest of the ideas mentioned in L::M) - I can create custom TMPL_xxx tags (which erally rocks for some = situtations). You can find this information on my website: = http://members.optusnet.com.au/mathew Hope this helps, Mathew ----- Original Message -----=20 From: "Johan Kuuse" <ku...@re...> To: <htm...@li...>; = <cg...@li...> Sent: Thursday, May 26, 2005 3:40 AM Subject: [htmltmpl] HTML::Template and Locale::Maketext Hi, This is a long post, so feel free to stop reading now. :-) Anyone has used HTML::Template and Locale::Maketext together? Or HTML::Template in any I18N project? My doubts are mostly what approach I should use. The application I planning to start is not that big, but I always liked=20 separating things: a. .pl files - For the Perl programmer. b. .html files - for the web designer c. .po and/or .pm files containing just languages hashes - for the = language=20 translator (ok, Perl hashes, but very readable even for a = non-programmer) To keep things separated, there is a problem: 1. If, on one hand, I want to use one single HTML::Template for the = output in=20 different languages, the template itself cannot have any "fixed strings" = in=20 one languages, but has to be filled up only with <TMPL_VAR NAME=3Dxxx> = tags for=20 every single message. This makes the job tougher for the web designer (the web page preview = will be=20 almost unreadable). 2. If, on the other hand, one HTML::Template per language, the = translator has=20 to know some HTML to create a HTML::Template with "fixed strings" in = her/his=20 language. And this means that the web designer will end up with one = template=20 per language, which also is undesirable. Any suggestions are appreciated. I will try explaining details of the problem by using a couple of = examples: Approach 1, using one template for all languages: hello.pl # ---------------------------------------- #!/usr/bin/perl -w use HTML::Template; use MyApp:I18N; my $locale =3D $ARGV || 'en'; # Use English as default my $lh =3D MyApp::I18N->get_handle($locale) || die "Can't get a language = handle!"; # open the html template my $template =3D HTML::Template->new(filename =3D> = 'hello.world.tmpl.html'); # fill in some parameters $template->param( HELLO_WORLD =3D> $lh->maketext("Hello, world!"), WELCOME_TO_THIS_WEB_SITE =3D> $lh->maketext("Welcome to this web = site."), ); # send the obligatory Content-Type and print the template output print "Content-Type: text/html\n\n", $template->output; # ---------------------------------------- hello.world.tmpl.html # ---------------------------------------- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title><TMPL_VAR NAME=3DHELLO_WORLD></title> </head> <body> <b><TMPL_VAR NAME=3DHELLO_WORLD></b> <p><TMPL_VAR NAME=3DWELCOME_TO_THIS_WEB_SITE></p> </body> </html> # ---------------------------------------- MyApp/I18N/en.pm # ---------------------------------------- package MyApp::I18N::es; # Spanish language messages use base qw(MyApp::I18N); use strict; use vars qw(%Lexicon); %Lexicon =3D ( # Message to translator: Start here! "Hello, world!" =3D> "Hello, world!", "Welcome to this website." =3D> "Welcome to this website.", # Message to translator: Stop here! ); # ---------------------------------------- MyApp/I18N/es.pm # ---------------------------------------- package MyApp::I18N::es; # Spanish language messages use base qw(MyApp::I18N); use strict; use vars qw(%Lexicon); %Lexicon =3D ( # Mensaje a traductor: =A1Empieza aqu=ED! "Hello, world!" =3D> "=A1Hola, mundo!", "Welcome to this website." =3D> "Bienvenido a este sitio web.", # Mensaje a traductor: =A1Termina aqu=ED! ); # ---------------------------------------- MyApp/I18N/se.pm # ---------------------------------------- package MyApp::I18N::es; # Swedish language messages use base qw(MyApp::I18N); use strict; use vars qw(%Lexicon); %Lexicon =3D ( # Meddelande till =F6vers=E4ttaren: B=F6rja h=E4r! "Hello, world!" =3D> "Hej, v=E4rlden!", "Welcome to this website." =3D> "V=E4lkommen till den h=E4r = webbsajten.", # Meddelande till =F6vers=E4ttaren: Sluta h=E4r! ); # ---------------------------------------- Approach 2, using one template per language: hello.pl # ---------------------------------------- #!/usr/bin/perl -w use HTML::Template; my $locale =3D $ARGV || 'en'; # Use English as default my $filename =3D 'hello.world.tmpl.html.' . $locale; # open the html template my $template =3D HTML::Template->new(filename =3D> $filename); # send the obligatory Content-Type and print the template output print "Content-Type: text/html\n\n", $template->output; # ---------------------------------------- hello.world.tmpl.html.en # ---------------------------------------- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title>Hello, world!</title> </head> <body> <b>Hello, world!</b> <p>Welcome to this website.</p> </body> </html> # ---------------------------------------- hello.world.tmpl.html.es # ---------------------------------------- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title>=A1Hola, mundo!</title> </head> <body> <b>=A1Hola, mundo!</b> <p>Bienvenido a este sitio web.</p> </body> </html> # ---------------------------------------- hello.world.tmpl.html.se # ---------------------------------------- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title>Hej, v=E4rlden!</title> </head> <body> <b>Hej, v=E4rlden!</b> <p>V=E4lkommen till den h=E4r webbsajten.</p> </body> </html> # ---------------------------------------- Best Regards, Johan Kuuse ------------------------------------------------------- SF.Net email is sponsored by: GoToMeeting - the easiest way to = collaborate online with coworkers and clients while avoiding the high cost of travel = and communications. There is no equipment to buy and you can meet as often = as you want. Try it = free.http://ads.osdn.com/?ad_idt02&alloc_id=16135&op=3Dick _______________________________________________ Html-template-users mailing list Htm...@li... https://lists.sourceforge.net/lists/listinfo/html-template-users |
From: Hugues de M. <hu...@ma...> - 2005-05-26 13:34:54
|
Hi all, I just finished the translation of web pages in our product (which uses = H::T) from French to English, and now I'm *sure* that having as many = template files as languages is definitely a bad idea (except if your = product/site doesn't evolve anymore, which could not be a good news ;-). = So i was looking for a different way of localizing my H::T I was thinking about a solution using HTML::Template::Expr and adding a = function that would directly call maketext. I'm not sure it's really = different from Matthew's solution (except for the difference between = Locale::Maketext and Locale::Makephrase). In my idea, the template could look like: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title><TMPL_VAR EXPR=3D"maketext('Hello, world!')"></title> </head> <body> <b><TMPL_VAR EXPR=3D"maketext('Hello, world!')"></b> <p><TMPL_VAR EXPR=3D"maketext('Welcome to this website.')"></p> <!-- We could use H::T variables to have things like this : --> <p><TMPL_VAR EXPR=3D"maketext('We have [quant,_1,visitor] today', = visitor_count)"></p> </body> </html> With an appropriate H::T filter, the template could be more readable, = for example using a {{ ... }} notation which would result in: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title>{{Hello, world!}}></title> ...and so on. I didn't had time to implement it, but I guess this could work. Did = someone try this ? Best, Hugues ----- Original Message -----=20 From: "Mathew Robertson" <mat...@re...> To: "Johan Kuuse" <ku...@re...> Cc: <htm...@li...> Sent: Thursday, May 26, 2005 12:50 PM Subject: Re: [htmltmpl] HTML::Template and Locale::Maketext Hi Johan, About 18 months ago I had a similar requirement, and thus eventually got = around to looking at Locale::Maketext. One of the key points that the = documentation makes, is that English is not a language that you should = derive your second language from. One problem I had with L::M was that = it still forces some of the "English is a base language" syndrome onto = the programmer. I also like the idea of not needing to distribute .po = files for every GUI change. So I created Locale::MakeText. Then I patch H::T so that it is capable of supporting custom TMPL_xxx = tags. Then I wrote a module to combine the two. The end result is that my translations are: - stored in a database (whenever I do do a GUI update, translations can = happen in real-time) - singular/plural aware (and the rest of the ideas mentioned in L::M) - I can create custom TMPL_xxx tags (which erally rocks for some = situtations). You can find this information on my website: = http://members.optusnet.com.au/mathew Hope this helps, Mathew ----- Original Message -----=20 From: "Johan Kuuse" <ku...@re...> To: <htm...@li...>; = <cg...@li...> Sent: Thursday, May 26, 2005 3:40 AM Subject: [htmltmpl] HTML::Template and Locale::Maketext Hi, This is a long post, so feel free to stop reading now. :-) Anyone has used HTML::Template and Locale::Maketext together? Or HTML::Template in any I18N project? My doubts are mostly what approach I should use. The application I planning to start is not that big, but I always liked=20 separating things: a. .pl files - For the Perl programmer. b. .html files - for the web designer c. .po and/or .pm files containing just languages hashes - for the = language=20 translator (ok, Perl hashes, but very readable even for a = non-programmer) To keep things separated, there is a problem: 1. If, on one hand, I want to use one single HTML::Template for the = output in=20 different languages, the template itself cannot have any "fixed strings" = in=20 one languages, but has to be filled up only with <TMPL_VAR NAME=3Dxxx> = tags for=20 every single message. This makes the job tougher for the web designer (the web page preview = will be=20 almost unreadable). 2. If, on the other hand, one HTML::Template per language, the = translator has=20 to know some HTML to create a HTML::Template with "fixed strings" in = her/his=20 language. And this means that the web designer will end up with one = template=20 per language, which also is undesirable. Any suggestions are appreciated. I will try explaining details of the problem by using a couple of = examples: Approach 1, using one template for all languages: hello.pl # ---------------------------------------- #!/usr/bin/perl -w use HTML::Template; use MyApp:I18N; my $locale =3D $ARGV || 'en'; # Use English as default my $lh =3D MyApp::I18N->get_handle($locale) || die "Can't get a language = handle!"; # open the html template my $template =3D HTML::Template->new(filename =3D> = 'hello.world.tmpl.html'); # fill in some parameters $template->param( HELLO_WORLD =3D> $lh->maketext("Hello, world!"), WELCOME_TO_THIS_WEB_SITE =3D> $lh->maketext("Welcome to this web = site."), ); # send the obligatory Content-Type and print the template output print "Content-Type: text/html\n\n", $template->output; # ---------------------------------------- hello.world.tmpl.html # ---------------------------------------- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title><TMPL_VAR NAME=3DHELLO_WORLD></title> </head> <body> <b><TMPL_VAR NAME=3DHELLO_WORLD></b> <p><TMPL_VAR NAME=3DWELCOME_TO_THIS_WEB_SITE></p> </body> </html> # ---------------------------------------- MyApp/I18N/en.pm # ---------------------------------------- package MyApp::I18N::es; # Spanish language messages use base qw(MyApp::I18N); use strict; use vars qw(%Lexicon); %Lexicon =3D ( # Message to translator: Start here! "Hello, world!" =3D> "Hello, world!", "Welcome to this website." =3D> "Welcome to this website.", # Message to translator: Stop here! ); # ---------------------------------------- MyApp/I18N/es.pm # ---------------------------------------- package MyApp::I18N::es; # Spanish language messages use base qw(MyApp::I18N); use strict; use vars qw(%Lexicon); %Lexicon =3D ( # Mensaje a traductor: =A1Empieza aqu=ED! "Hello, world!" =3D> "=A1Hola, mundo!", "Welcome to this website." =3D> "Bienvenido a este sitio web.", # Mensaje a traductor: =A1Termina aqu=ED! ); # ---------------------------------------- MyApp/I18N/se.pm # ---------------------------------------- package MyApp::I18N::es; # Swedish language messages use base qw(MyApp::I18N); use strict; use vars qw(%Lexicon); %Lexicon =3D ( # Meddelande till =F6vers=E4ttaren: B=F6rja h=E4r! "Hello, world!" =3D> "Hej, v=E4rlden!", "Welcome to this website." =3D> "V=E4lkommen till den h=E4r = webbsajten.", # Meddelande till =F6vers=E4ttaren: Sluta h=E4r! ); # ---------------------------------------- Approach 2, using one template per language: hello.pl # ---------------------------------------- #!/usr/bin/perl -w use HTML::Template; my $locale =3D $ARGV || 'en'; # Use English as default my $filename =3D 'hello.world.tmpl.html.' . $locale; # open the html template my $template =3D HTML::Template->new(filename =3D> $filename); # send the obligatory Content-Type and print the template output print "Content-Type: text/html\n\n", $template->output; # ---------------------------------------- hello.world.tmpl.html.en # ---------------------------------------- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title>Hello, world!</title> </head> <body> <b>Hello, world!</b> <p>Welcome to this website.</p> </body> </html> # ---------------------------------------- hello.world.tmpl.html.es # ---------------------------------------- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title>=A1Hola, mundo!</title> </head> <body> <b>=A1Hola, mundo!</b> <p>Bienvenido a este sitio web.</p> </body> </html> # ---------------------------------------- hello.world.tmpl.html.se # ---------------------------------------- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title>Hej, v=E4rlden!</title> </head> <body> <b>Hej, v=E4rlden!</b> <p>V=E4lkommen till den h=E4r webbsajten.</p> </body> </html> # ---------------------------------------- Best Regards, Johan Kuuse ------------------------------------------------------- SF.Net email is sponsored by: GoToMeeting - the easiest way to = collaborate online with coworkers and clients while avoiding the high cost of travel = and communications. There is no equipment to buy and you can meet as often = as you want. Try it = free.http://ads.osdn.com/?ad_idt02&alloc_id=16135&op=3Dick _______________________________________________ Html-template-users mailing list Htm...@li... https://lists.sourceforge.net/lists/listinfo/html-template-users ------------------------------------------------------- SF.Net email is sponsored by: GoToMeeting - the easiest way to = collaborate online with coworkers and clients while avoiding the high cost of travel = and communications. There is no equipment to buy and you can meet as often = as you want. Try it = free.http://ads.osdn.com/?ad_idt02&alloc_id=16135&op=3Dick _______________________________________________ Html-template-users mailing list Htm...@li... https://lists.sourceforge.net/lists/listinfo/html-template-users |
From: Johan K. <ku...@re...> - 2005-05-26 16:51:37
|
Hi, I haven't tested neither of your solutions/suggestions yet (Markus, Mathew,= =20 Hugues), even if they all look interesting. Anyway, what Markus mentioned about using HTML::Parser is an approach that = may=20 make things easier for the web designer. What I'm looking for is an approach that would be as painless as possible f= or=20 all parts - both the programmer, web designer and translator. On this list we're all programmers, so we know what's the best solution - f= or=20 the programmer. I don't really know at what degree one should think and plan of the web=20 designer's and translator's tasks. I do agree that storing the language phrases in a database is an elegant=20 solution. But to me, as an example, telling the translator: "Please fill in the Itali= an=20 (Greek, Swahili, Klingon, Whatever) column in this Excel sheet I just sent = to=20 you, export it as CSV, and then please upload the csv file to my database=20 server, which will incorproate your language in the application immediately= =2E"=20 is just equally one important part of an elegant solution. Use a database to avoid .po files - easy for the programmer. Tell the translator what to do, without assuming any programming skills.=20 The role of the web designer if more complicated. Personally, I have only worked together with web designers who are very=20 focused on design, and not so much on HTML itself. My personal taste has been more minimalistic (a UNIX programmer's disease? = ;-)=20 than the web designer's, so the discussions/compromises have included=20 limiting graphics etc., but never programming issues related to the HTML=20 templates. One alternative is to: =2D Save a copy of the output from a web page in one language (in the=20 "undesigned" way I created the HTML template). =2D Pass the copy to the web designer. =2D Parse the re-designed page (through HTML::Parser) to replace the=20 words/phrases with the original <TMPL_VAR...> tags? =2D Optionally, save a copy of the output from the (now redesigned) web pag= e in=20 another language, and pass it to the web designer, just to assure her/him=20 that the same page looks fine in two different languages. The other alternative is to ask the web designer to work directly with the= =20 templates. In this case, using this document (my example)... =2D--------------------------------------- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title><TMPL_VAR NAME=3DHELLO_WORLD></title> </head> <body> <b><TMPL_VAR NAME=3DHELLO_WORLD></b> <p><TMPL_VAR NAME=3DWELCOME_TO_THIS_WEB_SITE></p> </body> </html> =2D--------------------------------------- =2E.. or this document (Hugues' example)... =2D--------------------------------------- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title><TMPL_VAR EXPR=3D"maketext('Hello, world!')"></title> </head> <body> <b><TMPL_VAR EXPR=3D"maketext('Hello, world!')"></b> <p><TMPL_VAR EXPR=3D"maketext('Welcome to this website.')"></p> <!-- We could use H::T variables to have things like this : --> <p><TMPL_VAR EXPR=3D"maketext('We have [quant,_1,visitor] today',=20 visitor_count)"></p> </body> </html> =2D--------------------------------------- =2E.. would both show a blank web page in Quanta's "preview mode", and some= =20 yellow highlighted <TMPL_..> tags in DreamWeaver's preview mode. While this may be enough for a more "HTML-focused" web designer, it is=20 definitely not the case for a more "design-focused" web designer. Of course, this discussion about <TMPL_...> tags for the web designer isn't= =20 only an issue for multiling=FCal web pages, but it is where it comes to an= =20 extreme, as there is no common text at all in the HTML document, only=20 template tags all over. Any comment and/or experiences (especially on working with web designers) a= re=20 appreciated. Regards, Johan On Thursday 26 May 2005 07:31, Hugues de Mazancourt wrote: > Hi all, > > I just finished the translation of web pages in our product (which uses > H::T) from French to English, and now I'm *sure* that having as many > template files as languages is definitely a bad idea (except if your > product/site doesn't evolve anymore, which could not be a good news ;-). = So > i was looking for a different way of localizing my H::T > > I was thinking about a solution using HTML::Template::Expr and adding a > function that would directly call maketext. I'm not sure it's really > different from Matthew's solution (except for the difference between > Locale::Maketext and Locale::Makephrase). In my idea, the template could > look like: > > <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> > <html> > <head> > <title><TMPL_VAR EXPR=3D"maketext('Hello, world!')"></title> > </head> > <body> > <b><TMPL_VAR EXPR=3D"maketext('Hello, world!')"></b> > <p><TMPL_VAR EXPR=3D"maketext('Welcome to this website.')"></p> > <!-- We could use H::T variables to have things like this : --> > <p><TMPL_VAR EXPR=3D"maketext('We have [quant,_1,visitor] today', > visitor_count)"></p> </body> > </html> > > With an appropriate H::T filter, the template could be more readable, for > example using a {{ ... }} notation which would result in: > > <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> > <html> > <head> > <title>{{Hello, world!}}></title> > ...and so on. > > I didn't had time to implement it, but I guess this could work. Did someo= ne > try this ? > > Best, > > Hugues > > > ----- Original Message ----- > From: "Mathew Robertson" <mat...@re...> > To: "Johan Kuuse" <ku...@re...> > Cc: <htm...@li...> > Sent: Thursday, May 26, 2005 12:50 PM > Subject: Re: [htmltmpl] HTML::Template and Locale::Maketext > > > Hi Johan, > > About 18 months ago I had a similar requirement, and thus eventually got > around to looking at Locale::Maketext. One of the key points that the > documentation makes, is that English is not a language that you should > derive your second language from. One problem I had with L::M was that it > still forces some of the "English is a base language" syndrome onto the > programmer. I also like the idea of not needing to distribute .po files > for every GUI change. > > So I created Locale::MakeText. > > Then I patch H::T so that it is capable of supporting custom TMPL_xxx tag= s. > > Then I wrote a module to combine the two. > > The end result is that my translations are: > - stored in a database (whenever I do do a GUI update, translations can > happen in real-time) - singular/plural aware (and the rest of the ideas > mentioned in L::M) - I can create custom TMPL_xxx tags (which erally rocks > for some situtations). > > > You can find this information on my website: =20 > http://members.optusnet.com.au/mathew > > Hope this helps, > Mathew > > > > ----- Original Message ----- > From: "Johan Kuuse" <ku...@re...> > To: <htm...@li...>; <cg...@li...= t> > Sent: Thursday, May 26, 2005 3:40 AM > Subject: [htmltmpl] HTML::Template and Locale::Maketext > > > Hi, > > This is a long post, so feel free to stop reading now. :-) > > Anyone has used HTML::Template and Locale::Maketext together? > Or HTML::Template in any I18N project? > > My doubts are mostly what approach I should use. > The application I planning to start is not that big, but I always liked > separating things: > a. .pl files - For the Perl programmer. > b. .html files - for the web designer > c. .po and/or .pm files containing just languages hashes - for the langua= ge > translator (ok, Perl hashes, but very readable even for a non-programmer) > > To keep things separated, there is a problem: > 1. If, on one hand, I want to use one single HTML::Template for the output > in different languages, the template itself cannot have any "fixed string= s" > in one languages, but has to be filled up only with <TMPL_VAR NAME=3Dxxx> > tags for every single message. > This makes the job tougher for the web designer (the web page preview will > be almost unreadable). > 2. If, on the other hand, one HTML::Template per language, the translator > has to know some HTML to create a HTML::Template with "fixed strings" in > her/his language. And this means that the web designer will end up with o= ne > template per language, which also is undesirable. > > Any suggestions are appreciated. > > I will try explaining details of the problem by using a couple of example= s: > > Approach 1, using one template for all languages: > hello.pl > # ---------------------------------------- > #!/usr/bin/perl -w > use HTML::Template; > use MyApp:I18N; > my $locale =3D $ARGV || 'en'; # Use English as default > my $lh =3D MyApp::I18N->get_handle($locale) || die "Can't get a language > handle!"; > # open the html template > my $template =3D HTML::Template->new(filename =3D> 'hello.world.tmpl.html= '); > # fill in some parameters > $template->param( > HELLO_WORLD =3D> $lh->maketext("Hello, world!"), > WELCOME_TO_THIS_WEB_SITE =3D> $lh->maketext("Welcome to this web site."), > ); > # send the obligatory Content-Type and print the template output > print "Content-Type: text/html\n\n", $template->output; > # ---------------------------------------- > hello.world.tmpl.html > # ---------------------------------------- > <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> > <html> > <head> > <title><TMPL_VAR NAME=3DHELLO_WORLD></title> > </head> > <body> > <b><TMPL_VAR NAME=3DHELLO_WORLD></b> > <p><TMPL_VAR NAME=3DWELCOME_TO_THIS_WEB_SITE></p> > </body> > </html> > # ---------------------------------------- > MyApp/I18N/en.pm > # ---------------------------------------- > package MyApp::I18N::es; > # Spanish language messages > use base qw(MyApp::I18N); > use strict; > use vars qw(%Lexicon); > %Lexicon =3D ( > # Message to translator: Start here! > "Hello, world!" =3D> "Hello, world!", > "Welcome to this website." =3D> "Welcome to this website.", > # Message to translator: Stop here! > ); > # ---------------------------------------- > MyApp/I18N/es.pm > # ---------------------------------------- > package MyApp::I18N::es; > # Spanish language messages > use base qw(MyApp::I18N); > use strict; > use vars qw(%Lexicon); > %Lexicon =3D ( > # Mensaje a traductor: =A1Empieza aqu=ED! > "Hello, world!" =3D> "=A1Hola, mundo!", > "Welcome to this website." =3D> "Bienvenido a este sitio web.", > # Mensaje a traductor: =A1Termina aqu=ED! > ); > # ---------------------------------------- > MyApp/I18N/se.pm > # ---------------------------------------- > package MyApp::I18N::es; > # Swedish language messages > use base qw(MyApp::I18N); > use strict; > use vars qw(%Lexicon); > %Lexicon =3D ( > # Meddelande till =F6vers=E4ttaren: B=F6rja h=E4r! > "Hello, world!" =3D> "Hej, v=E4rlden!", > "Welcome to this website." =3D> "V=E4lkommen till den h=E4r webbsajten.= ", > # Meddelande till =F6vers=E4ttaren: Sluta h=E4r! > ); > # ---------------------------------------- > > > Approach 2, using one template per language: > hello.pl > # ---------------------------------------- > #!/usr/bin/perl -w > use HTML::Template; > my $locale =3D $ARGV || 'en'; # Use English as default > my $filename =3D 'hello.world.tmpl.html.' . $locale; > # open the html template > my $template =3D HTML::Template->new(filename =3D> $filename); > # send the obligatory Content-Type and print the template output > print "Content-Type: text/html\n\n", $template->output; > # ---------------------------------------- > hello.world.tmpl.html.en > # ---------------------------------------- > <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> > <html> > <head> > <title>Hello, world!</title> > </head> > <body> > <b>Hello, world!</b> > <p>Welcome to this website.</p> > </body> > </html> > # ---------------------------------------- > hello.world.tmpl.html.es > # ---------------------------------------- > <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> > <html> > <head> > <title>=A1Hola, mundo!</title> > </head> > <body> > <b>=A1Hola, mundo!</b> > <p>Bienvenido a este sitio web.</p> > </body> > </html> > # ---------------------------------------- > hello.world.tmpl.html.se > # ---------------------------------------- > <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> > <html> > <head> > <title>Hej, v=E4rlden!</title> > </head> > <body> > <b>Hej, v=E4rlden!</b> > <p>V=E4lkommen till den h=E4r webbsajten.</p> > </body> > </html> > # ---------------------------------------- > > > Best Regards, > Johan Kuuse > > > > ------------------------------------------------------- > SF.Net email is sponsored by: GoToMeeting - the easiest way to collaborate > online with coworkers and clients while avoiding the high cost of travel > and communications. There is no equipment to buy and you can meet as often > as you want. Try it free.http://ads.osdn.com/?ad_idt02&alloc_id=16135&op= =3Dick > _______________________________________________ > Html-template-users mailing list > Htm...@li... > https://lists.sourceforge.net/lists/listinfo/html-template-users > > > > ------------------------------------------------------- > SF.Net email is sponsored by: GoToMeeting - the easiest way to collaborate > online with coworkers and clients while avoiding the high cost of travel > and communications. There is no equipment to buy and you can meet as often > as you want. Try it free.http://ads.osdn.com/?ad_idt02&alloc_id=16135&op= =3Dick > _______________________________________________ > Html-template-users mailing list > Htm...@li... > https://lists.sourceforge.net/lists/listinfo/html-template-users > > > > ------------------------------------------------------- > SF.Net email is sponsored by: GoToMeeting - the easiest way to collaborate > online with coworkers and clients while avoiding the high cost of travel > and communications. There is no equipment to buy and you can meet as often > as you want. Try it > free.http://ads.osdn.com/?ad_idt02&alloc_id=16135&op=3DClick > _______________________________________________ > Html-template-users mailing list > Htm...@li... > https://lists.sourceforge.net/lists/listinfo/html-template-users =2D-=20 Johan Kuuse ku...@re... Thu May 26 07:52:39 2005 |
From: Markus S. <m.s...@gm...> - 2005-05-26 20:20:30
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Johan Kuuse schrieb: > Of course, this discussion about <TMPL_...> tags for the web designer isn't > only an issue for multilingüal web pages, but it is where it comes to an > extreme, as there is no common text at all in the HTML document, only > template tags all over. The HTML::Parser based solution just avoids this mess: * You have simple XHTML in your template * Use <tmpl_var> only where necessary for program flow * Let Locale::Maketext or Locale::MakePhrase handle the translations in a filter process * A patched HTML::Template then has to cache the translated templates And for translation you can either * use a natural language as basis and have an AUTO entry in Locale::Maketext's dictionary for this language * or create artificial strings which get translated into *every* language (has advantages if you have many and very different languages) The web designer then only has to take care that the maximum space a translated string may require will be accommodated, but other than that can use the normal tools without having to take care of custom tags in the html code Kind regards Markus -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iD8DBQFCli+RxxUzQSse11ARAkPgAJ4pn0M4h0P7kvEm2LnxghQVFvTYewCfWhvn WgGYWAorQDAhMQCmojFXJ0k= =AK78 -----END PGP SIGNATURE----- |
From: Mathew R. <mat...@re...> - 2005-05-27 00:15:45
|
Translation issues aside, one of the best parts of storing translations = in a database is that you can quite easily build a web interface to the = database table. You write a script which greps your = source-code/templates so that it inserts the new strings, and deletes = any unused ones. This works really well for web pages as you simply set the encoding to = UTF8, provide a combobox of selectable languages / regions, provide a = textarea for the string input and a submit button. As a programmer I = never need to speak to the translators as they simply use the web = interface. The only real issue that the programmer has to do is to set a few extra = template variables: TMPL_VAR document_charset TMPL_VAR document_direction TMPL_VAR document_language TMPL_VAR document_direction_default TMPL_VAR document_direction_inverse The first three should be used in your document headers and occasionaly = in table headers. The other two are used for formatting within tables, = so that your text/image alignment comes out correct for the language. hope this helps Mathew |
From: Mathew R. <mat...@re...> - 2005-05-27 00:48:10
|
> The only real issue that the programmer has to do is to set a few = extra template variables: > > TMPL_VAR document_charset > TMPL_VAR document_direction > TMPL_VAR document_language > TMPL_VAR document_direction_default > TMPL_VAR document_direction_inverse > > The first three should be used in your document headers and = occasionaly in table headers. > The other two are used for formatting within tables, so that your = text/image alignment comes out correct for the language. I should clarify, the reason for the direction var's is that in some = languages, the text can be written lefto-to-right or right-to-left = depending on where the person comes from. As such, these variables = should be a user preference so that they can change them as appropriate. The values for them should be: document_direction : "LTR" or "RTL" document_direction_default : should be the same as = document_direction document_direction_inverse : should be the alternate of = document_direction_default cheers, Mathew |
From: Hugues de M. <hu...@ma...> - 2005-05-27 07:38:54
|
Hi, Just about <TMPL_xxx > tags in the template file: don't forget that you=20= can use H::T's 'filter' option and thus define your own syntax.=20 Personally, I've turned all the <TMPL_x > into a {%... %} notation, so=20= that '<TMPL_VAR NAME=3D"foo">' now reads '{%VAR NAME=3D"foo"%}' in my=20 templates. This works in Dreamweaver (at least a my translator's=20 version). As I suggested, you can use this kind of filter to "hide" calls to=20 maketext (or whatever localisation method) into a more web-designer=20 friendly way. For example you could use {{ ... }}=A0to hide <TMPL_VAR=20 EXPR=3Dmaketext('...')>. This could yield to: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <html> <head> <title>{{Hello, world!}}></title> </head> <body> <b>{{Hello, world!}}></b> <p>{{Welcome to this website.}}></p> <!-- We could use H::T variables to have things like this : --> <p>{{We have [quant,_1,visitor] today,, visitor_count}}></p> </body> </html> (definition of the filter is left as an exercise to the reader ;-) A a side effect, this can help the designer keep in mind that all text=20= chunks will be localised independently, so that he/she should avoid=20 things like: <TR> <TD>{{Do you want}}</TD> <TD>{{to}} <select name=3D"action"><option = value=3D"del">{{delete}}</option><option=20 value=3D"keep">{{keep}}</option></select> </TD> <TR> Where "to" would have to be translated using some unambiguous=20 correspondence which doesn't exist for every languages (at least for=20 French, this "to" would disappear - in other contexts, not). Best, Hugues PS: I know that this doesn't solve the cache issue, as template is=20 re-evaluated for every display, so that you should mix this approach=20 with Mark's caching modifications.= |
From: Mathew R. <mat...@re...> - 2005-05-27 08:55:43
|
> For example you could use {{ ... }} to hide <TMPL_VAR = EXPR=3Dmaketext('...')>. This could yield to: > > <p>{{We have [quant,_1,visitor] today,, visitor_count}}></p> = </body> The syntax of: We have [quant,_1,visitor] today was one of the my dislikes of Locale::Maketext. Locale::Maketext assumes that the programmer knows: a) the method to call; this case 'quant' (is there ever any other method = to call?) b) that _1 applies to the word 'visitor' - in reality the sales = department may not like the wording that was chosen by the programmer. It also compile-caches the result so that the only way to change the = value, it to re-start the Perl interpreter. With Locale::MakePhrase, it contains an expression engine so that the = translator can do the equivalent of: _1 =3D=3D 0 : "No visitors" _1 =3D=3D 1 : "Only one visitor" ... ie: it scarifices CPU cycles, to allow the expressions to be changed at = runtime. Mathew |