Log::R...xtract(3pm)

πŸ“¦
version 1.04 Β· 2 versions
, in ubuntu resolute, ubuntu stonking

πŸ‘‘ NAME πŸ’…

okay so bestie, welcome to Log::Report::Template::Extract β€” it literally collects translatable strings from template files. That's the whole vibe. Also if you spotted the manual page name, it's Log::R...xtract(3pm) (they truncate it, it's giving abbreviation energy, we love that for them).

πŸ¦‹ INHERITANCE πŸ¦‹

Log::Report::Template::Extract
  is a Log::Report::Extract

so yeah, it's a child class, it inherited all the good genes ✨

🌸 SYNOPSIS 🌸

first use case β€” added in Log-Report-Template v0.90, iconic behavior:

# Added Log-Report-Template v0.90
# First use of this module: extract msgids from various kinds
# of text-files, usually web templates.
# See script "xgettext-perl" for standard wrapper script

my $extr = Log::Report::Template::Extract->new(
  lexicon => '/usr/share/locale',
  domain  => 'my-web-site',
  pattern => 'TT2-loc',
);
$extr->process('website/page.html');  # many times
$extr->showStats;
$extr->write;

second use case β€” connecting to Template::Toolkit, and yes the DETAILS chapter below has the tea:

# Second use: connect to Template::Toolkit
# See DETAILS chapter below

[% loc("Greetings {name},", name => client.name) %]
[% | loc(name => client.name) %]Greetings {name}[% END %]
[% 'Greetings {name}' | loc(name => client.name) %]

πŸŽ€ DESCRIPTION πŸŽ€

So this module? It's here to help you maintain the POT files β€” the ones that list all the translatable strings from template files (or honestly any other flat text files) β€” by updating the list of message-ids kept inside them. Lowkey essential.

Once you've done the initiation thing, you gotta call the process() method for every single file in the domain, and the existing PO files will get updated accordingly. No cap.

If no translations exist yet, one $textdomain.po file will be created as your little starting point 🫢. Copy that file into $textdomain/$lang.po.

It extends "DESCRIPTION" in Log::Report::Extract.

πŸ’œ METHODS πŸ’œ

Extends "METHODS" in Log::Report::Extract.

✨ Constructors ✨

Extends "Constructors" in Log::Report::Extract.

$class->new(%options)

here's the option table, look at her:

-Option --Defined in          --Default
 charset  Log::Report::Extract  'utf-8'
 domain                         <required>
 lexicon  Log::Report::Extract  <required>
 pattern                        <C<undef>>
  • charset => STRING
  • domain => DOMAIN β€” there's no syntax for specifying domains in templates (yet, bestie, yet), so you gotta be explicit about the collection we're making right now.
  • lexicon => DIRECTORY
  • pattern => PREDEFINED|CODE β€” the DETAILS section below explains this in detail (their spelling, not mine, but we move).

πŸ”₯ Accessors πŸ”₯

Extends "Accessors" in Log::Report::Extract.

  • $obj->addPot($domain, $pot, %options) β€” inherited, see "Accessors" in Log::Report::Extract
  • $obj->charset() β€” inherited, see "Accessors" in Log::Report::Extract
  • $obj->domain()
  • $obj->domains() β€” inherited, see "Accessors" in Log::Report::Extract
  • $obj->index() β€” inherited, see "Accessors" in Log::Report::Extract
  • $obj->pattern()
  • $obj->pots($domain) β€” inherited, see "Accessors" in Log::Report::Extract

🌈 Processors 🌈

Extends "Processors" in Log::Report::Extract.

  • $obj->cleanup(%options) β€” inherited, see "Processors" in Log::Report::Extract
  • $obj->process($filename, %options) β€” updates the domains mentioned in the $filename. Every textdomain defined in the file gets updated automatically, but nothing gets written before all the files were processed. Improves the base, see "Processors" in Log::Report::Extract.
-Option --Default
 charset  'utf-8'
 pattern  <from new(pattern)>
  • charset => STRING β€” the character encoding used in this template file.
  • pattern => PREDEFINED|CODE β€” go read the DETAILS section about this.
  • $obj->showStats( [$domains] ) β€” inherited, see "Processors" in Log::Report::Extract
  • $obj->store( $domain, $filename, $linenr, $context, $msg, [$msg_plural] ) β€” inherited, see "Processors" in Log::Report::Extract
  • $obj->write( [$domain], %options ) β€” inherited, see "Processors" in Log::Report::Extract

🌟 DETAILS 🌟

🧚 Scan Patterns 🧚

Different template systems have different conventions for marking which strings need translating. It's giving chaos, honestly.

Predefined for Template-Toolkit

There is not a single convention for translations in "Template-Toolkit" (see Template), so you have to specify which version of TT you're using and which function name you wanna use. In extreme cases you can even build separate translation tables just by providing using functions. (iykyk)

For instance:

pattern => 'TT2-loc'

will scan for:

[% loc("msgid", key => value, ...) %]
[% loc('msgid', key => value, ...) %]
[% loc("msgid|plural", count, key => value, ...) %]

[% INCLUDE
     title = loc('something')
 %]

[% | loc(n => name) %]hi {n}[% END %]
[% 'hi {n}' | loc(n => name) %]

For "TT1", the brackets can either be '[%...%]' or '%%...%%'. The function name is treated case-sensitive (respect the case, bestie). Some people prefer 'l()' or 'L()'.

The code needed:

# during initiation of the webserver, once in your script (before fork)
my $lexicons   = 'some-directory-for-translation-tables';
my $pots = Log::Report::Translator::POT->new(lexicons => $lexicons);

my $templater  = Log::Report::Template->new(...);
my $domain     = $templater->addTextdomain(
    name     => $domainname,
    function => 'loc',
);
$domain->configure(translator => $pots);

# part of the processing per page
$vars{translate_to} = 'nl_NL.utf8';
$templater->process($template, \%vars, \$output);

To generate the pod tables, run in the shell something like:

xgettext-perl -p $lexicons --template TT2-loc \
    --domain $textdomain  $templates_dir

If you wanna implement your own extractor β€” to avoid "xgettext-perl" β€” you need to run something like this:

my $extr = Log::Report::Template::Extract->new(
  lexicon => $output,
  charset => 'utf-8',
  domain  => $domain,
  pattern => 'TT2-loc',
);
$extr->process($_) for @filenames;
$extr->write;

πŸŽ€ Use in combination with contexts πŸŽ€

This example extends the previous one with context sensitive translations, as implemented by Log::Report::Translator::Context. Periodt.

Let's say that the translation of some of the sentences on the website depends on the gender of the person being addressed. An example of the use in a TT2 template:

[% loc("{name<gender} forgot his key", name => person.name) %]

The extraction script xgettext-perl will expand this into two records in the PO file, respectively with msgctxt attribute 'gender=male' and 'gender=female'.

When your PO-files are not generated by 'xgettext-perl', you do not need a separate domain configuration file:

$domain->configure(
  context_rules => +{gender => ['male','female']},
  translator    => $translator,
);

When your PO-files are generated by 'xgettext-perl', you need to share the context-rules between that msgid extractor and your runtime code. That same file needs to be passed with the 'domain' parameter to the script.

# add context_rules either explicit or via 'config' filename
$domain->configure(
  config     => 'my/own/$domain.conf',
  translator => $translator,
);

Now, when you generate the pages, you need to set up the right context. In this case, we set up the gender of the person who gets addressed. (The name 'gender' is good for examples, but quite non-descriptive. Maybe 'user_gender' is more maintainable β€” just a thought πŸ‘€)

$domain->setContext( +{gender => 'male'} );  # or ('gender=male')
$domain->setContext( "gender=male" );        # same

πŸ’€ DIAGNOSTICS πŸ’€

  • Fault: cannot read template from $file: $! β€” cast by process()
  • Warning: msgid '$msgid' contains html escapes, don't do that. File $file line $linenr β€” cast by process()
  • Error: need pattern to scan for, either via new() or process() β€” cast by process()
  • Error: no context tags allowed in plural `$msgid' β€” cast by store()
  • Info: processing file $file in $charset β€” cast by process()
  • Info: starting new textdomain $domain, template in $filename β€” cast by write()
  • Error: template extract requires explicit domain β€” cast by new()
  • Error: template syntax error, no END in $fn line $line β€” cast by process()
  • Error: unknown pattern $pattern β€” cast by process()

🫢 SEE ALSO 🫢

This module is part of Log-Report-Template version 1.04, built on November 04, 2025. Website: http://perl.overmeer.net/CPAN/ (go look, it's cute)

⭐ LICENSE ⭐

For contributors see file ChangeLog.

This software is copyright (c) 2017-2025 by Mark Overmeer.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.


and that's the whole manual bestie, no notes πŸ’– this little page was served up as perl v5.40.1 on 2026-01-24, under the very truncated name Log::R...xtract(3pm) β€” slay, go extract some msgids, you got this πŸ‘‘βœ¨

πŸ“¦ where this page comes from