.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Petal::I18N 3pm" .TH Petal::I18N 3pm "2020-05-22" "perl v5.30.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Petal::I18N \- Attempt at implementing ZPT I18N for Petal .SH "SYNOPSIS" .IX Header "SYNOPSIS" in your Perl code: .PP .Vb 2 \& use Petal; \& use Petal::TranslationService::Gettext; \& \& my $translation_service = new Petal::TranslationService::Gettext ( \& locale_dir => \*(Aq/path/to/my/app/locale\*(Aq, \& target_lang => gimme_target_lang(), \& ); \& \& my $template = new Petal ( \& file => \*(Aqexample.html\*(Aq, \& translation_service => $translation_service \& ); \& \& # we want to internationalize to the h4x0rz 31337 l4nGu4g3z. w00t! \& my $translation_service = Petal::TranslationService::h4x0r\->new(); \& my $template = new Petal ( \& file => \*(Aqsilly_example.xhtml\*(Aq, \& translation_service => $ts, \& ); \& \& print $template\->process (); .Ve .SH "I18N Howto" .IX Header "I18N Howto" .SS "Preparing your templates:" .IX Subsection "Preparing your templates:" Say your un-internationalized template looks like this: .PP .Vb 4 \& \& \& the logo of our organisation \& \&

Hello, \& Joe.

\& \&

How are you today?

\& \& .Ve .PP You need to markup your template according to the \s-1ZPT I18N\s0 specification, which can be found at http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/ZPTInternationalizationSupport .PP .Vb 11 \& \& \& the logo of our organisation \&

Hello, Joe.

\&

How are you today?

\& \& .Ve .SS "Extracting I18N strings:" .IX Subsection "Extracting I18N strings:" Once your templates are marked up properly, you will need to use a tool to extract the I18N strings into .pot (po template) files. To my knowledge you can use i18ndude (standalone python executable), i18nextract.py (part of Zope 3), or I18NFool. .PP I use i18ndude to find strings which are not marked up properly with i18n:translate attributes and I18NFool for extracting strings and managing .po files. .PP Assuming you're using i18nfool: .PP .Vb 7 \& mkdir \-p /path/to/my/app/locale \& cd /path/to/my/app/locale \& i18nfool\-extract /path/to/my/template/example.html \& mkdir en \& mkdir fr \& mkdir es \& i18nfool\-update .Ve .PP Then you translate the .po files into their respective target languages. When that's done, you type: .PP .Vb 2 \& cd /path/to/my/app/locale \& i18nfool\-build .Ve .PP And it builds all the .mo files. .SS "Making your application use a Gettext translation service:" .IX Subsection "Making your application use a Gettext translation service:" Previously you might have had: .PP .Vb 3 \& use Petal; \& # lotsa code here \& my $template = Petal\->new (\*(Aqexample.html\*(Aq); .Ve .PP This needs to become: .PP .Vb 8 \& use Petal; \& use Petal::TranslationService::Gettext; \& # lotsa code here \& my $template = Petal\->new (\*(Aqexample.html\*(Aq); \& $template\->{translation_service} = Petal::TranslationService::Gettext\->new ( \& locale_dir => \*(Aq/path/to/my/app/locale\*(Aq, \& target_lang => gimme_language_code(), \& ); .Ve .PP Where \fBgimme_language_code()\fR returns a language code depending on \s-1LC_LANG,\s0 content-negotiation, config-file, or whatever mechanism you are using to decide which language is desired. .SS "And then?" .IX Subsection "And then?" And then that's it! Your application should be easily internationalizable. There are a few traps / gotchas thought, which are described below. .SH "BUGS, TRAPS, GOTCHAS and other niceties" .IX Header "BUGS, TRAPS, GOTCHAS and other niceties" .SS "Translation Phase" .IX Subsection "Translation Phase" The translation step takes place \s-1ONLY ONCE THE TEMPLATE HAS BEEN PROCESSED.\s0 .PP So if you have: .PP .Vb 3 \&

Hello, \& Joe \&

.Ve .PP It most likely will not work because the tal:replace would remove the tag and also the i18n:name in the process. .PP This means that instead of receiving something such as: .PP .Vb 1 \& Hello, ${user_login} .Ve .PP The translation service would receive: .PP .Vb 1 \& Hello, Fred Flintstone .Ve .PP Or .PP .Vb 1 \& Hello, Joe SixPack .Ve .PP etc. .PP To fix this issue, use tal:content instead of tal:replace and leave the span and its i18n:name attribute. .SS "Character sets" .IX Subsection "Character sets" I haven't worried too much about them (yet) so if you run into trouble join the Petal mailing list and we'll try to fix any issues together. .SS "Limitations" .IX Subsection "Limitations" At the moment, Petal::I18N supports the following constructs: .ie n .IP "xmlns:i18n=""http://xml.zope.org/namespaces/i18n""" 4 .el .IP "xmlns:i18n=``http://xml.zope.org/namespaces/i18n''" 4 .IX Item "xmlns:i18n=http://xml.zope.org/namespaces/i18n" .PD 0 .IP "i18n:translate" 4 .IX Item "i18n:translate" .IP "i18n:domain" 4 .IX Item "i18n:domain" .IP "i18n:name" 4 .IX Item "i18n:name" .IP "i18n:attribute" 4 .IX Item "i18n:attribute" .PD .PP It does *NOT* (well, not yet) support i18n:source, i18n:target or i18n:data.