NAME
Text::PO::Gettext - A GNU Gettext implementation
SYNOPSIS
use Text::PO::Gettext;
my $po = Text::PO::Gettext->new || die( Text::PO::Gettext->error, "\n" );
my $po = new Gettext({
category => 'LC_MESSAGES',
debug => 3,
domain => "com.example.api",
locale => 'ja-JP',
path => "/home/joe/locale",
use_json => 1,
}) || die( Text::PO::Gettext->error, "\n" );
VERSION
v0.1.0
DESCRIPTION
This module is used to access the data in either po
, mo
or json
file and provides various methods to access those data.
The conventional way to use GNU gettext is to set the global environment variable LANGUAGE
(not LANG
by the way. GNU gettext only uses LANGUAGE
), then set the "setlocale" in POSIX to the language such as:
use Locale::gettext;
use POSIX ();
POSIX::setlocale( &POSIX::LC_ALL, 'ja_JP' );
my $d = Locale::gettext->domain( 'com.example.api' );
And then in your application, you would write a statement like:
print $d->get( 'Hello!' );
Or possibly using direct access to the C function:
use Locale::gettext;
use POSIX ();
POSIX::setlocale( &POSIX::LC_ALL, 'ja_JP' );
textdomain( 'com.example.api' );
And then:
print gettext( 'Hello!' );
See Locale::gettext for more on this.
This works fine, but has the inconvenience that it uses the global LANGUAGE
environment variable and makes it less than subpar as to the necessary flexibility when using multiple domains and flipping back and forth among locales.
Thus comes a more straightforward object-oriented interface offered by this module.
You instantiate an object, passing the domain, the locale and the filesystem path where the locale data resides.
my $po = Text::PO::Gettext->new(
domain => 'com.example.api',
locale => 'ja_JP',
path => '/some/where/locale'
);
print $po->gettext( 'Hello!' );
This will load into memory the locale data whether they are stored as .po
, .mo
or even .json
file, thus making calls to "gettext" super fast since they are in memory.
More than one locale can be loaded, each with its own Text::PO::Gettext object
This distribution comes with its Javascript library equivalent. See the share
folder alone with its own test units.
Also, there is a script in scripts
that can be used to transcode .po
or .mo
files into json format and vice versa.
Still, it is better to convert the original .po
files to json using the po.pl
utility that comes in this Text::PO distribution since it would allow the standalone JavaScript library to read json-based po files. For example:
./po.pl --as-json --output /home/joe/www/locale/ja_JP/LC_MESSAGES/com.example.api.json ./ja_JP.po
This api supports locale that use hyphens or underscore in them such as en-GB
or en_GB
. You can use either, it will be converted internally.
CONSTRUCTOR
new
Takes the following options and returns a Gettext object.
- category
-
If category is defined, such as
LC_MESSAGES
(by default), it will be used when building the path.On the web, using the path is questionable.
See the GNU documentation for more information on this.
- domain
-
The portable object domain, such as
com.example.api
- locale
-
The locale, such as
ja_JP
, oren
, or it could even contain a dash instead of an underscore, such asen-GB
. Internally, though, this will be converted to underscore. - path
-
The uri path where the gettext localised data are.
This is used to form a path along with the locale string. For example, with a locale of
ja_JP
and a domain ofcom/example.api
, if the path were/locale
, the data po json data would be fetched from/locale/ ja_JP/LC_MESSAGES/com.example.api.json
METHODS
addItem
This takes a locale
, a message id and its localised version and it will add this to the current dictionary for the current domain.
$po->addItem( 'ja_JP', 'Hello!' => "今日は!" );
category
The category to use. This defaults to LC_MESSAGES
, but if you prefer you can nix its use by making it undefined, or empty:
my $po = Text::PO::Gettext->new(
category => '',
domain => 'com.example.api',
locale => 'ja_JP',
path => '/some/where/locale'
);
# Setting category to empty string will have the module get the po data
# under C</some/where/locale/ja_JP/com.example.api.json> for example.
print $po->gettext( 'Hello!' );
charset
Returns a string containing the value of the charset encoding as defined in the Content-Type
header.
$po->charset()
contentEncoding
Returns a string containing the value of the header Content-Encoding
.
$po->contentEncoding();
contentType
Returns a string containing the value of the header Content-Type
.
$po->contentType(); # text/plain; charset=utf-8
currentLang
Return the current globally used locale. This is the value found in environment variables LANGUAGE
or LANG
. Note that GNU gettext only recognises LANGUAGE
and thus, this is different from the locale
set in the Gettext class object using </setLocale> or upon class object instantiation.
dgettext
Takes a domain and a message id and returns the equivalent localised string if any, otherwise the original message id.
$po->dgettext( 'com.example.auth', 'Please enter your e-mail address' );
# Assuming the locale currently set is ja_JP, this would return:
# 電子メールアドレスをご入力下さい。
dngettext
Same as "ngettext", but takes also a domain as first argument. For example:
$po->ngettext( 'com.example.auth', '%d comment awaiting moderation', '%d comments awaiting moderation', 12 );
# Assuming the locale is ru_RU, this would return:
# %d комментариев ожидают проверки
domain
Sets or gets the domain.
$po->domain( 'com.example.api' );
By doing so, this will call "textdomain" and load the associated data from file, if any are found.
exists
Provided with a locale, and this returns true if the locale exists in the current domain, or false otherwise.
fetchLocale
Given an original string (msgid), this returns an array of <span> html element each for one language and its related localised content. For example:
my $array = $po->fetchLocale( "Hello!" );
# Returns:
<span lang="de-DE">Grüß Gott!</span>
<span lang="fr-FR">Salut !</span>
<span lang="ja-JP">今日は!</span>
<span lang="ko-KR">안녕하세요!</span>
This is designed to be added to the html, and based on lang
attribute of the html
tag, and using the following css trick, this will automatically display the right localised data:
[lang=de-DE] [lang=en-GB],
[lang=de-DE] [lang=fr-FR],
[lang=de-DE] [lang=ja-JP],
[lang=de-DE] [lang=ko-KR],
[lang=en-GB] [lang=de-DE],
[lang=en-GB] [lang=fr-FR],
[lang=en-GB] [lang=ja-JP],
[lang=en-GB] [lang=ko-KR],
[lang=fr-FR] [lang=de-DE],
[lang=fr-FR] [lang=en-GB],
[lang=fr-FR] [lang=ja-JP],
[lang=fr-FR] [lang=ko-KR],
[lang=ja-JP] [lang=de-DE],
[lang=ja-JP] [lang=en-GB]
[lang=ja-JP] [lang=fr-FR],
[lang=ja-JP] [lang=ko-KR]
{
display: none !important;
visibility: hidden !important;
}
getDataPath
This takes no argument and will check for the environment variables TEXTDOMAINDIR
. If found, it will use this in lieu of the path option used during object instantiation.
It returns the value found. This is just a helper method and does not affect the value of the path property set during object instantiation.
getDomainHash
This takes an optional hash of parameters and return the global hash dictionary used by this class to store the localised data.
# Will use the default domain as set in po.domain
my $data = $po->getDomainHash();
# Explicitly specify another domain
my $data = $po->getDomainHash( domain => "net.example.api" );
# Specify a domain and a locale
my $l10n = $po->getDomainHash( domain => "com.example.api", locale => "ja_JP" );
Possible options are:
- domain The domain for the data, such as
com.example.api
- locale The locale to return the associated dictionary.
getLangDataPath
Contrary to its JavaScript equivalent, this takes no parameter. It returns the value of the environment variable TEXTLOCALEDIR
if found.
This is used internally during object instantiation when the path parameter is not provided.
getLanguageDict
Provided with a locale, such as ja_JP
and this will return the dictionary for the current domain and the given locale.
getLocale
Returns the locale set for the current object, such as fr_FR
or ja_JP
Locale returned are always formatted for the server-side, which means having an underscore rather than an hyphen like in the web environment.
getLocales
Provided with a msgid
(i.e. an original text) and this will call "fetchLocale" and return those span
tags as a string containing their respective localised content, joined by a new line
getLocalesf
This is similar to "getLocale", except that it does a sprintf internally before returning the resulting value.
getMetaKeys
Returns an array of the meta field names used.
getMetaValue
Provided with a meta field name and this returns its corresponding value.
getPlural
Calls "plural" in Text::PO and returns an array object (Module::Generic::Array) with 2 elements.
See "plural" in Text::PO for more details.
getText
Provided with an original string, and this will return its localised equivalent if it exists, or by default, it will return the original string.
getTextf
Provided with an original string, and this will get its localised equivalent that wil be used as a template for the sprintf function. The resulting formatted localised content will be returned.
gettext
Provided with a msgid
represented by a string, and this return a localised version of the string, if any is found and is translated, otherwise returns the msgid
that was provided.
$po->gettext( "Hello" );
# With locale of fr_FR, this would return "Bonjour"
See the global function "_" for more information.
isSupportedLanguage
Provided with a locale such as fr-FR
or ja_JP
no matter whether an underscore or a dash is used, and this will return true if the locale has already been loaded and thus is supported. False otherwise.
language
Returns a string containing the value of the header Language
.
$po->language();
languageTeam
Returns a string containing the value of the header Language-Team
.
$po->languageTeam();
lastTranslator
Returns a string containing the value of the header Last-Translator
.
$po->lastTranslator();
mimeVersion
Returns a string containing the value of the header MIME-Version
.
$po->mimeVersion();
locale
Returns the locale set in the object. if sets, this will trigger the (re)load of po data by calling "textdomain"
locale_unix
Provided with a locale, such as en-GB
and this will return its equivalent formatted for server-side such as en_GB
locale_web
Provided with a locale, such as en_GB
and this will return its equivalent formatted for the web such as en-GB
ngettext
Takes an original string (a.k.a message id), the plural version of that string, and an integer representing the applicable count. For example:
$po->ngettext( '%d comment awaiting moderation', '%d comments awaiting moderation', 12 );
# Assuming the locale is ru_RU, this would return:
# %d комментариев ожидают проверки
path
Sets or gets the filesystem path to the base directory containing the locale data:
$po->path( '/locale' ); # /locale contains en_GB/LC_MESSAGES/com.example.api.mo for example
plural
Sets or gets the definition for plural for the current domain and locale.
It takes and returns an array reference of 2 elements:
- 0. An integer representing the various plural forms available, starting from 1
- 1. An expression to be evaluated resulting in an offset for the right plural form. For example:
-
n>1
or more complex for Russian:
(n==1) ? 0 : (n%10==1 && n%100!=11) ? 3 : ((n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2)
pluralForms
Returns a string containing the value of the header Plural-Forms
.
$po->pluralForms();
po_object
Returns the Text::PO object used.
poRevisionDate
Returns a string containing the value of the header PO-Revision-Date
.
$po->poRevisionDate();
potCreationDate
Returns a string containing the value of the header POT-Creation-Date
.
$po->potCreationDate();
projectIdVersion
Returns a string containing the value of the header Project-Id-Version
.
$po->projectIdVersion();
reportBugsTo
Returns a string containing the value of the header Report-Msgid-Bugs-To
.
$po->reportBugsTo();
textdomain
Given a string representing a domain, such as com.example.api
and this will load the .json
(if the "use_json" option is enabled), .po
or .mo
file found in that order.
use_json
Takes a boolean and if set, Text::PO::Gettext will use a json po data if it exists, otherwise it will use a .po
file or a .mo
file in that order of preference.
_get_po
Returns the Text::PO object used.
AUTHOR
Jacques Deguest <jack@deguest.jp>
SEE ALSO
COPYRIGHT & LICENSE
Copyright(c) 2021 DEGUEST Pte. Ltd. DEGUEST Pte. Ltd.