Provided by: libpetal-perl_2.25-1_all bug


       Petal::I18N - Attempt at implementing ZPT I18N for Petal


       in your Perl code:

         use Petal;
         use Petal::TranslationService::Gettext;

         my $translation_service = new Petal::TranslationService::Gettext (
             locale_dir  => '/path/to/my/app/locale',
             target_lang => gimme_target_lang(),

         my $template = new Petal (
             file => 'example.html',
             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 => 'silly_example.xhtml',
             translation_service => $ts,

         print $template->process ();

I18N Howto

   Preparing your templates:
       Say your un-internationalized template looks like this:

         <html xmlns:tal="">
             <img src="/images/my_logo.png"
                  alt="the logo of our organisation" />

                <span petal:content="user_name">Joe</span>.</p>

             <p>How are you today?</p>

       You need to markup your template according to the ZPT I18N specification, which can be
       found at

         <html xmlns:tal=""
             <img src="/images/my_logo.png"
                  alt="the logo of our organisation"
                  i18n:attributes="alt" />
             <p i18n:translate="">Hello, <span petal:content="user_name">Joe</span>.</p>
             <p i18n:translate="">How are you today?</p>

   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), (part of Zope 3), or I18NFool.

       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.

       Assuming you're using i18nfool:

         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

       Then you translate the .po files into their respective target languages. When that's done,
       you type:

         cd /path/to/my/app/locale

       And it builds all the .mo files.

   Making your application use a Gettext translation service:
       Previously you might have had:

         use Petal;
         # lotsa code here
         my $template = Petal->new ('example.html');

       This needs to become:

         use Petal;
         use Petal::TranslationService::Gettext;
         # lotsa code here
         my $template = Petal->new ('example.html');
         $template->{translation_service} = Petal::TranslationService::Gettext->new (
             locale_dir  => '/path/to/my/app/locale',
             target_lang => gimme_language_code(),

       Where gimme_language_code() returns a language code depending on LC_LANG, content-
       negotiation, config-file, or whatever mechanism you are using to decide which language is

   And then?
       And then that's it! Your application should be easily internationalizable.  There are a
       few traps / gotchas thought, which are described below.

BUGS, TRAPS, GOTCHAS and other niceties

   Translation Phase
       The translation step takes place ONLY ONCE THE TEMPLATE HAS BEEN PROCESSED.

       So if you have:

         <p i18n:translate="">Hello,
           <span i18n:name="user_login" tal:replace="self/user_login">Joe</span>

       It most likely will not work because the tal:replace would remove the <span> tag and also
       the i18n:name in the process.

       This means that instead of receiving something such as:

         Hello, ${user_login}

       The translation service would receive:

         Hello, Fred Flintstone


         Hello, Joe SixPack


       To fix this issue, use tal:content instead of tal:replace and leave the span and its
       i18n:name attribute.

   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.

       At the moment, Petal::I18N supports the following constructs:


       It does *NOT* (well, not yet) support i18n:source, i18n:target or i18n:data.