Log::R...xtract(3pm)
π 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=> STRINGdomain=> 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=> DIRECTORYpattern=> 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 byprocess() - Warning: msgid
'$msgid'contains html escapes, don't do that. File$fileline$linenrβ cast byprocess() - Error: need pattern to scan for, either via new() or process() β cast by
process() - Error: no context tags allowed in plural
`$msgid'β cast bystore() - Info: processing file
$filein$charsetβ cast byprocess() - Info: starting new textdomain
$domain, template in$filenameβ cast bywrite() - Error: template extract requires explicit domain β cast by
new() - Error: template syntax error, no END in
$fnline$lineβ cast byprocess() - Error: unknown pattern
$patternβ cast byprocess()
π«Ά 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
- ubuntu resolute: liblog-report-template-perl 1.04-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: liblog-report-template-perl 1.04-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms