NAME
Gettext - A GNU Gettext JavaScript implementation
SYNOPSIS
let po = new Gettext({
domain: "com.example.api",
# Get the lang attribute value from <html>
# Can also use document.getElementsByTagName('html')[0].getAttribute('lang')
# or in jQuery: $(':root').attr('lang')
locale: document.documentElement.lang,
# Under which uri can be found the localised data arborescence?
# Alternatively, you can set a <link rel="gettext" href="/locale" />
# or even one specific by language:
# <link rel="gettext" lang="ja_JP" href="/locale/ja" />
path: "/locale",
debug: true
});
VERSION
v0.1.0
DESCRIPTION
This is a standalone JavaScript library using class model to enable the
reading of json-based po files as well as ".mo" files. Even though it
can read ".mo" files, it is better to convert the original ".po" files
to json using the "po.pl" utility that comes in this Text::PO
distribution. For example:
./po.pl --as-json --output /home/joe/www/locale/ja_JP/com.example.api.json ./ja_JP.po
The class model does not use ES6, but rather one smart invention by John
Resig (creator of jQuery), making it usable even on older browser
versions.
Because on the service side, in Unix environments, the locale value uses
underscore, such as "ja_JP" while the web-side uses locale with a dash
such as "ja-JP", to harmonise and given we are dealing with po files, we
use internally the underscore version, converting it, if necessary.
See the section "TESTING" below for testing.
CONSTRUCTOR
new
Takes the following options and returns a Gettext object.
*domain*
The portable object domain, such as "com.example.api"
*locale*
The locale, such as "ja_JP", or "en", or it could even contain a
dash instead of an underscore, such as "en-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 of "com/example.api",
if the path were "/locale", the data po json data would be fetched
from "/locale/ja_JP/com.example.api.json"
You will note that the path does not include "LC_MESSAGES" since
under the web context, it makes no sense at all. See the GNU
documentation
<https://www.gnu.org/software/libc/manual/html_node/Using-gettextize
d-software.html> for more information on this.
CORE METHODS
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"
Note that you can also call it with the special function "_", such as:
_("Hello");
See the global function "_" for more information.
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:
# 電子メールアドレスをご入力下さい。
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 комментариев ожидают проверки
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 комментариев ожидают проверки
EXTENDED 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.
charset
Returns a string containing the value of the charset encoding as defined
in the "Content-Type" header.
p.charset()
contentEncoding
Returns a string containing the value of the header "Content-Encoding".
p.contentEncoding();
contentType
Returns a string containing the value of the header "Content-Type".
p.contentType(); # text/plaiin; charset=utf-8
currentLang
Return the current globally used locale. This is the value found in
<html lang="fr-FR">
and thus, this is different from the "locale" set in the Gettext class
object using </setLocale> or upon class object instantiation.
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:
var array = p.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>
getData
Takes an hash of options and perform an HTTP query and return a promise.
The accepted options are:
*headers*
An hash of field-value pairs to be used in the request header.
*method*
The HTTP method to be used, such as "GET" or "POST"
*params*
An hash of key-value pairs to be set and encoded in the http request
query.
*responseType*
The content-type expected in response. This is used to set it to
"arraybuffer" to load ".mo" (machine object) files.
*url*
The url to make the query to.
getDataPath
This takes no argument and will check among the "link" html tags for one
with an attribute "rel" with value "gettext" and no "lang" attribute. 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
var data = po.getDomainHash();
// Explicitly specify another domain
var data = po.getDomainHash({ domain: net.example.api });
// Specify a domain and a locale
var 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
This takes a locale as its unique parameter.
Similar to </getDataPath>, this will search among the "link" html tags
for those with the attribute "rel" with value "gettext" and an existing
"lang" attribute. If found it returns the value of the "href" attribute.
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 web, which means having an
hyphen rather than an underscore like in Unix environment.
getLocales
Provided with a locale and this will call "fetchLocale" and return those
"span" tags as a string, joined by a new line
getLocalesf
This is similar to "getLocale", except that it does a sprintf internally
before returning the resulting value.
getMoData
Provided with an uri and this will make an http query to fetch the
remove ".mp" (machine object) file.
It calls "getData" and returns a promise.
getPlural
Returns the array representing the plural rule for the current domain.
The array returned is composed of 2 elements:
1. An integer representing the number of possible plural forms
2. A string representing an expression using "n" as the count provided.
This string is to be evaluated and will return an offset value used to
get the right localised plural content in an array of "msgstr"
The value returned cannot exceed the integer.
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.
getTextDomain
Returns a string representing the domain currently set, such as
"com.example.api"
getXhrObject
Return an XMLHttpRequest object compliant with older versions of
Microsoft browsers.
isSupportedLanguage
Provided with a locale and this returns true if the language is
supported or false otherwise.
This basically look at the current dictionaries loaded so far for
various languages and check if the locale specified in argument is among
them.
language
Returns a string containing the value of the header "Language".
p.language();
languageTeam
Returns a string containing the value of the header "Language-Team".
p.languageTeam();
lastTranslator
Returns a string containing the value of the header "Last-Translator".
p.lastTranslator();
loadDomainData
Provided with an hash of options and this will get the data, parse it,
save it.
This is called by "setTextDomain" and "setLocale"
mimeVersion
Returns a string containing the value of the header "MIME-Version".
p.mimeVersion();
pluralForms
Returns a string containing the value of the header "Plural-Forms".
p.pluralForms();
poRevisionDate
Returns a string containing the value of the header "PO-Revision-Date".
p.poRevisionDate();
potCreationDate
Returns a string containing the value of the header "POT-Creation-Date".
p.potCreationDate();
projectIdVersion
Returns a string containing the value of the header
"Project-Id-Version".
p.projectIdVersion();
reportBugsTo
Returns a string containing the value of the header
"Report-Msgid-Bugs-To".
p.reportBugsTo();
setLocale
Sets a new locale to be used looking forward.
po.setLocale( 'fr_FR' ); # po.setLocale( 'fr-FR' ); would also work
setTextDomain
Sets a new domain to be used looking forward. Setting a new domain, will
trigger the Gettext class to fetch its data by executing an http "GET"
query using "getData" unless the domain is already registered and
loaded.
po.setTextDomain( 'com.example.auth' );
GLOBAL FUNCTION
_
The special function "_" is standard for gettext. This is a wrapper to
the following:
Assuming the global variable TEXTDOMAIN is set, or else that there is a
script tag:
<script id="gettext" type="application/json">
{
domain: "com.example.api",
debug: true,
defaultLocale: "en_US"
}
</script>
If no locale is defined in the json, then it will check for the
attribute "lang" of the "html" tag, such as:
<html lang="fr-FR">
And will instantiate a "Gettext" object, passing it the *domain*,
*debug* and *locale* parameters as options, and will return the value
returned by "po.gettext"
If an improper "msgid" (undefined or null or empty) is provided or there
is no "domain" to be found, an error will be raised.
CLASS MOParser
new
Takes an optional hash of options. Currently supported option is
*debug*.
Instantiate a new MOParser object and returns it.
parse
This takes a buffer and an hash of options and returns an hash
representing the msgid-msgstr.
Acceptable options are:
*encoding*
Character encoding used to decode data
_getEndianness
Returns the file endianness used. True if it is little endian or false
if it is big endian.
_parseHeader
Read the binary data and returns an hash of field-value pairs
representing the ".mo" (machine object) file headers.
_readTranslationPair
Read the binary data and returns an hash with properties "id" and "str"
corresponding to the next "msgid" and "msgstr" found.
_splitPlurals
Takes a msgid string and a msgstr string and split them to get an array
of single and plural representations.
It returns an hash with properties "id" representing the "msgid" and
"str" containing an array of "msgstr"
TESTING
On the command line, go to the top directory of the Text::PO
distribution and launch a small web server using python or anything else
you would like:
For Perl:
# With HTTP::Daemon
perl -MHTTP::Daemon -e '$d = HTTP::Daemon->new(LocalPort => 8000) or +die $!; while
($c = $d->accept) { while ($r = $c->get_request) { +$c->send_file_response(".".$r->url->path) } }'
# After installing the module HTTP::Server::Brick
perl -MHTTP::Server::Brick -e '$s=HTTP::Server::Brick->new(port=>8000); $s->mount("/"=>{path=>"."}); $s->start'
# If you have Plack::App::Directory
perl -MPlack::App::Directory -e 'Plack::App::Directory->new(root=>".");' -p 8000
# With IO::All
perl -MIO::All -e 'io(":8000")->fork->accept->(sub { $_[0] < io(-x $1 +? "./$1 |" : $1) if /^GET \/(.*) / })'
For python 2:
python -m SimpleHTTPServer
For python 3:
python3 -m http.server
Or using ruby:
ruby -run -e httpd -p 8000 .
Or with php:
php -S localhost:8000
Or possibly with nodejs if you have it installed:
# to install http-server
npm install -g http-server
# or using brew:
brew install http-server
# then
http-server -c-1 -p 8000
More information here <https://www.npmjs.com/package/http-server>
Then, you can go to <http://localhost:8000/share/test.html>
If all goes well, you will see the result of all the test performed, and
they should all be marked ok
AUTHOR
Jacques Deguest <jack@deguest.jp>
SEE ALSO
Text::PO::Element, Text::PO::MO
<https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html>,
<https://en.wikipedia.org/wiki/Gettext>
COPYRIGHT & LICENSE
Copyright (c) 2020-2021 DEGUEST Pte. Ltd.
You can use, copy, modify and redistribute this package and associated
files under the same terms as Perl itself.