dwww Home | Manual pages | Find package

Locale...Domain(3pm)  User Contributed Perl Documentation  Locale...Domain(3pm)

NAME
       Locale::TextDomain - Perl Interface to Uniforum Message Translation

SYNOPSIS
        use Locale::TextDomain ('my-package', @locale_dirs);

        use Locale::TextDomain qw (my-package);

        my $translated = __"Hello World!\n";

        my $alt = $__{"Hello World!\n"};

        my $alt2 = $__->{"Hello World!\n"};

        my @list = (N__"Hello",
                    N__"World");

        printf (__n ("one file read",
                     "%d files read",
                     $num_files),
                $num_files);

        print __nx ("one file read", "{num} files read", $num_files,
                    num => $num_files);

        my $translated_context = __p ("Verb, to view", "View");

        printf (__np ("Files read from filesystems",
                      "one file read",
                      "%d files read",
                      $num_files),
                $num_files);

        print __npx ("Files read from filesystems",
                     "one file read",
                     "{num} files read",
                     $num_files,
                     num => $num_files);

DESCRIPTION
       The module Locale::TextDomain(3pm) provides a high-level interface to
       Perl message translation.

   Textdomains
       When you request a translation for a given string, the system used in
       libintl-perl follows a standard strategy to find a suitable message
       catalog containing the translation: Unless you explicitly define a name
       for the message catalog, libintl-perl will assume that your catalog is
       called 'messages' (unless you have changed the default value to
       something else via Locale::Messages(3pm), method textdomain()).

       You might think that his default strategy leaves room for optimization
       and you are right.  It would be a lot smarter if multiple software
       packages, all with their individual message catalogs, could be installed
       on one system, and it should also be possible that third-party
       components of your software (like Perl modules) can load their message
       catalogs, too, without interfering with yours.

       The solution is clear, you have to assign a unique name to your message
       database, and you have to specify that name at run-time.  That unique
       name is the so-called textdomain of your software package.  The name is
       actually arbitrary but you should follow these best-practice guidelines
       to ensure maximum interoperability:

       File System Safety
               In  practice,  textdomains  get  mapped into file names, and you
               should therefore make sure that the textdomain you choose  is  a
               valid filename on every system that will run your software.

       Case-sensitivity
               Textdomains  are  always  case-sensitive  (i.  e.  'Package' and
               'PACKAGE'  are  not  the  same).   However,  since  the  message
               catalogs  will  be  stored  on file systems, that may or may not
               distinguish case when looking up file names,  you  should  avoid
               potential conflicts here.

       Textdomain Should Match CPAN Name
               If  your  software  is  listed  as  a module on CPAN, you should
               simply  choose  the  name  on  CPAN  as  your  textdomain.   The
               textdomain for libintl-perl is hence 'libintl-perl'.  But please
               replace   all  periods  ('.')  in  your  package  name  with  an
               underscore because ...

       Internet Domain Names as a Fallback
               ... if your software is not a module listed on CPAN, as  a  last
               resort  you should use the Java(tm) package scheme, i. e. choose
               an internet domain that you are owner of (or ask the owner of an
               internet domain) and concatenate your preferred textdomain  with
               the  reversed  internet  domain.  Example: Your company runs the
               web-site  'www.foobar.org'  and  is  the  owner  of  the  domain
               'foobar.org'.    The  textdomain  for  your  company's  software
               'barfoos' should hence be 'org.foobar.barfoos'.

       If your software is likely to be installed in different versions on  the
       same  system,  it  is  probably  a  good  idea  to  append  some version
       information to your textdomain.

       Other systems are less strict with the naming scheme for textdomains but
       the phenomena known as Perl is actually a plethora of small, specialized
       modules and it is probably wisest to postulate some namespace  model  in
       order to avoid chaos.

   Binding textdomains to directories
       Once the system knows the textdomain of the message that you want to get
       translated  into  the  user's language, it still has to find the correct
       message catalog.  By default, libintl-perl will look up  the  string  in
       the  translation database found in the directories /usr/share/locale and
       /usr/local/share/locale (in that order).

       It is neither guaranteed that these  directories  exist  on  the  target
       machine,  nor  can  you  be sure that the installation routine has write
       access to these locations.  You can therefore instruct  libintl-perl  to
       search other directories prior to the default directories.  Specifying a
       different   search  directory  is  called  binding  a  textdomain  to  a
       directory.

       Beginning with version  1.20,  Locale::TextDomain  extends  the  default
       strategy  by  a Perl-specific approach.  If File::ShareDir is installed,
       it will look in the subdirectories named locale and LocaleData (in  that
       order)   in   the   directory   returned   by  "File::ShareDir::dist_dir
       ($textdomain)"  (if  File::ShareDir  is  installed),  and  check  for  a
       database  containing the message for your textdomain there.  This allows
       you to install your database in the Perl-specific shared directory using
       Module::Install's "install_share" directive or the Dist::Zilla  ShareDir
       plugin.

       If  File::ShareDir  is  not available, or if Locale::TextDomain fails to
       find the translation files in the File::ShareDir directory, it will next
       look in every directory found in the standard  include  path  @INC,  and
       check  for  a database containing the message for your textdomain there.
       Example: If the path /usr/lib/perl/5.8.0/site_perl is in your @INC,  you
       can        install        your        translation        files        in
       /usr/lib/perl/5.8.0/site_perl/LocaleData, and they will be found at run-
       time.

USAGE
       It  is  crucial  to  remember  that  you  use  Locale::TextDomain(3)  as
       specified  in the section "SYNOPSIS", that means you have to use it, not
       require it.  The module behaves  quite  differently  compared  to  other
       modules.

       The  most significant difference is the meaning of the list passed as an
       argument to the use() function.  It actually works like this:

           use Locale::TextDomain (TEXTDOMAIN, DIRECTORY, ...)

       The first argument (the first string passed to use()) is the  textdomain
       of  your package, optionally followed by a list of directories to search
       instead  of  the  Perl-specific  directories  (see  above:   /LocaleData
       appended to a File::ShareDir directory and every path in @INC).

       If  you are the author of a package 'barfoos', you will probably put the
       line

           use Locale::TextDomain 'barfoos';

       resp. for non-CPAN modules

           use Locale::TextDomain 'org.foobar.barfoos';

       in every module of your package that contains translatable  strings.  If
       your module has been installed properly, including the message catalogs,
       it will then be able to retrieve these translations at run-time.

       If  you  have  not  installed  the  translation  database in a directory
       LocaleData in the File::ShareDir directory or the standard include  path
       @INC   (or   in   the   system   directories   /usr/share/locale   resp.
       /usr/local/share/locale), you have to explicitly specify a  search  path
       by giving the names of directories (as strings!) as additional arguments
       to use():

           use Locale::TextDomain qw (barfoos ./dir1 ./dir2);

       Alternatively  you  can call the function bindtextdomain() with suitable
       arguments  (see  the  entry  for  bindtextdomain()  in  "FUNCTIONS"   in
       Locale::Messages).   If  you  do  so,  you  should  pass  "undef"  as an
       additional argument in order to avoid unnecessary lookups:

           use Locale::TextDomain ('barfoos', undef);

       You see that the arguments given to use() have nothing to do  with  what
       is  imported  into  your  namespace,  but  they  are rather arguments to
       textdomain(),   resp.   bindtextdomain().    Does   that    mean    that
       Locale::TextDomain exports nothing into your namespace? Umh, not exactly
       ...  in  fact it imports all functions listed below into your namespace,
       and hence you should not define conflicting  functions  (and  variables)
       yourself.

       So,  why  has Locale::TextDomain to be different from other modules?  If
       you  have  ever  written   software   in   C   and   prepared   it   for
       internationalization   (i18n),  you  will  probably  have  defined  some
       preprocessor macros like:

           #define _(String) dgettext ("my-textdomain", String)
           #define N_(String) String

       You only have to define that once in C,  and  the  textdomain  for  your
       package  is  automatically inserted into all gettext functions.  In Perl
       there is no such mechanism (at least it is not portable, option -P)  and
       using  the  gettext functions could become quite cumbersome without some
       extra fiddling:

           print dgettext ("my-textdomain", "Hello world!\n");

       This is no fun.  In C it would merely be a

           printf (_("Hello world!\n"));

       Perl has to be more concise and shorter than C ... see the next  section
       for how you can use Locale::TextDomain to end up in Perl with a mere

           print __"Hello World!\n";

EXPORTED FUNCTIONS
       All  functions  have  quite funny names on purpose.  In fact the purpose
       for that is quite clear: They should be short, operator-like,  and  they
       should not yell for conflicts with existing functions in your namespace.
       You  will  understand  it,  when  you  internationalize  your first Perl
       program or module.  Preparing it is more like marking strings  as  being
       translatable than inserting function calls.  Here we go:

       __ MSGID
           NOTE: This is a double underscore!

           The  basic  and most-used function.  It is a short-cut for a call to
           gettext() resp. dgettext(), and simply returns the  translation  for
           MSGID.  If your old code reads like this:

               print "permission denied";

           You will now write:

               print __"permission denied";

           That's  all,  the  string  will  be  output  in the user's preferred
           language, provided that you have installed a translation for it.

           Of course you can also use parentheses:

               print __("permission denied");

           Or even:

               print (__("permission denied"));

           In my eyes, the first version without parentheses looks best.

       __x MSGID, ID1 => VAL1, ID2 => VAL2, ...
           One of the nicest features in Perl is its capability to  interpolate
           variables into strings:

               print "This is the $color $thing.\n";

           This  nice  feature  might  con you into thinking that you could now
           write

               print __"This is the $color $thing.\n";

           Alas, that would be nice, but it is not possible.  Remember that the
           function __() serves both as an operator for translating strings and
           as a mark for translatable strings.  If the above string  would  get
           extracted from your Perl code, the un-interpolated form would end up
           in  the  message  catalog  because  when  parsing  your  code  it is
           unpredictable what values the variables $thing and $color will  have
           at  run-time (this fact is most probably one of the reasons you have
           written your program for).

           However, at run-time, Perl will have interpolated the values already
           before __() (resp. the underlying gettext() function) has  seen  the
           original  string.   Consequently  something  like  "This  is the red
           car.\n" will be looked up in the message catalog,  it  will  not  be
           found  (because  only  "This is the $color $thing.\n" is included in
           the  database),  and  the  original,  untranslated  string  will  be
           returned.   Honestly,  because  this  is almost always an error, the
           xgettext(1) program will bail out with a fatal error when  it  comes
           across that string in your code.

           There are two workarounds for that:

               printf __"This is the %s %s.\n", $color, $thing;

           But  that  has  several disadvantages: Your translator will only see
           the isolated string, and without the surrounding code it  is  almost
           impossible  to  interpret  it  correctly.   Of course, GNU emacs and
           other software capable of editing PO translation  files  will  allow
           you to examine the context in the source code, but it is more likely
           that  your  translator  will look for a less challenging translation
           project when she frequently comes across such messages.

           And even if she does understand the underlying programming, what  if
           she has to reorder the color and the thing like in French:

               msgid "This is the red car.\n";
               msgstr "Cela est la voiture rouge.\n"

           Zut alors! While it is possible to reorder the arguments to printf()
           and  friends,  it requires a syntax that is is nothing that you want
           to learn.

           So what? The Perl backend to GNU gettext has defined an  alternative
           format for interpolatable strings:

               "This is the {color} {thing}.\n";

           Instead   of  Perl  variables  you  use  place-holders  (legal  Perl
           variables are also legal place-holders) in curly  braces,  and  then
           you call

               print __x ("This is the {color} {thing}.\n",
                          thing => $thang,
                          color => $color);

           The  function  __x()  will  take the additional hash and replace all
           occurencies of the hash keys in curly braces with the  corresponding
           values.   Simple, readable, understandable to translators, what else
           would you  want?   And  if  the  translator  forgets,  misspells  or
           otherwise messes up some "variables", the msgfmt(1) program, that is
           used  to  compile  the  textual  translation  file  into  its binary
           representation will even choke on these errors and refuse to compile
           the translation.

       __n MSGID, MSGID_PLURAL, COUNT
           Whew! That looks complicated  ...  It  is  best  explained  with  an
           example.  We'll have another look at your vintage code:

               if ($files_deleted > 1) {
                   print "All files have been deleted.\n";
               } else {
                   print "One file has been deleted.\n";
               }

           Your  intent  is  clear, you wanted to avoid the cumbersome "1 files
           deleted".  This is okay for English, but other languages  have  more
           than  one plural form.  For example in Russian it makes a difference
           whether you want to say 1 file, 3 files or 6 files.   You  will  use
           three  different forms of the noun 'file' in each case.  [Note: Yep,
           very smart you are, the Russian word  for  'file'  is  in  fact  the
           English  word,  and  it is an invariable noun, but if you know that,
           you will also understand the rest despite this little simplification
           ...].

           That is the reason for the existence  of  the  function  ngettext(),
           that __n() is a short-cut for:

               print __n"One file has been deleted.\n",
                        "All files have been deleted.\n",
                        $files_deleted;

           Alternatively:

               print __n ("One file has been deleted.\n",
                          "All files have been deleted.\n",
                          $files_deleted);

           The  effect  is  always  the  same: libintl-perl will find out which
           plural form to pick for your user's language, and the output  string
           will always look okay.

       __nx MSGID, MSGID_PLURAL, COUNT, VAR1 => VAL1, VAR2 => VAL2, ...
           Bringing it all together:

               print __nx ("One file has been deleted.\n",
                           "{count} files have been deleted.\n",
                           $num_files,
                           count => $num_files);

           The  function  __nx()  picks  the  correct  plural  form  (also  for
           English!)   and  it  is  capable  of  interpolating  variables  into
           strings.

           Have  a  close look at the order of arguments: The first argument is
           the string in the singular, the second one is the plural string. The
           third one is an integer indicating the number of items.  This  third
           argument  is  only  used  to  pick  the  correct  translation.   The
           optionally  following  arguments  make  up   the   hash   used   for
           interpolation.  In the beginning it is often a little confusing that
           the  variable  holding  the number of items will usually be repeated
           somewhere in the interpolation hash.

       __xn MSGID, MSGID_PLURAL, COUNT, VAR1 => VAL1, VAR2 => VAL2, ...
           Does exactly the same thing as __nx().  In fact it is a common  typo
           promoted to a feature.

       __p MSGCTXT, MSGID
           This  is  much  like  __.  The  "p" stands for "particular", and the
           MSGCTXT is used to provide context to the translator.  This  may  be
           necessary  when  your  string is short, and could stand for multiple
           things. For example:

               print __p"Verb, to view", "View";
               print __p"Noun, a view", "View";

           The above may be "View" entries in a menu,  where  View->Source  and
           File->View  are  different  forms  of  "View", and likely need to be
           translated differently.

           A typical usage are GUI programs.  Imagine a  program  with  a  main
           menu  and  the  notorious  "Open"  entry  in  the  "File" menu.  Now
           imagine, there is another menu  entry  Preferences->Advanced->Policy
           where  you  have  a  choice  between  the  alternatives  "Open"  and
           "Closed".  In English, "Open" is the adequate text at  both  places.
           In  other  languages,  it is very likely that you need two different
           translations.  Therefore, you would now write:

               __p"File|", "Open";
               __p"Preferences|Advanced|Policy", "Open";

           In English, or if no translation can be found, the  second  argument
           (MSGID) is returned.

           This function was introduced in libintl-perl 1.17.

       __px MSGCTXT, MSGID, VAR1 => VAL1, VAR2 => VAL2, ...
           Like  __p(),  but supports variable substitution in the string, like
           __x().

               print __px("Verb, to view", "View {file}", file => $filename);

           See __p() and __x() for more details.

           This function was introduced in libintl-perl 1.17.

       __np MSGCTXT, MSGID, MSGID_PLURAL, COUNT
           This adds context to plural calls. It  should  not  be  needed  very
           often,  if  at all, due to the __nx() function. The type of variable
           substitution used in other  gettext  libraries  (using  sprintf-like
           sybols,  like  %s  or  %1)  sometimes  required context. For a (bad)
           example of this:

               printf (__np("[count] files have been deleted",
                           "One file has been deleted.\n",
                           "%s files have been deleted.\n",
                           $num_files),
                       $num_files);

           NOTE: The above usage is discouraged.  Just  use  the  __nx()  call,
           which provides inline context via the key names.

           This function was introduced in libintl-perl 1.17.

       __npx MSGCTXT, MSGID, MSGID_PLURAL, COUNT, VAR1 => VAL1, VAR2 => VAL2,
       ...
           This is provided for comleteness. It adds the variable interpolation
           into the string to the previous method, __np().

           It's usage would be like so:

               print __npx ("Files being permenantly removed",
                            "One file has been deleted.\n",
                            "{count} files have been deleted.\n",
                            $num_files,
                            count => $num_files);

           I  cannot  think of any situations requiring this, but we can easily
           support it, so here it is.

           This function was introduced in libintl-perl 1.17.

       N__(ARG1)
           A no-op function that simply echoes its  arguments  to  the  caller.
           Take the following piece of Perl:

               my @options = (
                   "Open",
                   "Save",
                   "Save As",
               );

               ...

               my $option = $options[1];

           Now  say  that  you  want  to  have  this  translatable.   You could
           sometimes simply do:

               my @options = (
                   __"Open",
                   __"Save",
                   __"Save As",
               );

               ...

               my $option = $options[1];

           But often times this will not be what you want, for example when you
           also need the unmodified original string.  Sometimes it may not even
           work, for example, when the  preferred  user  language  is  not  yet
           determined at the time that the list is initialized.

           In these cases you would write:

               my @options = (
                   N__"Open",
                   N__"Save",
                   N__"Save As",
               );

               ...

               my $option = __($options[1]);
               # or: my $option = dgettext ('my-domain', $options[1]);

           Now  all  the  strings  in  @options will be left alone, since N__()
           returns its arguments (one ore more) unmodified.  Nevertheless,  the
           string  extractor  will  be  able  to recognize the strings as being
           translatable.  And you  can  still  get  the  translation  later  by
           passing  the  variable  instead  of  the  string to one of the above
           translation functions.

       N__n (MSGID, MSGID_PLURAL, COUNT)
           Does exactly the same as N__().  You will use this form if you  have
           to mark the strings as having plural forms.

       N__p (MSGCTXT, MSGID)
           Marks MSGID as N__() does, but in the context MSGCTXT.

       N__np (MSGCTXT, MSGID, MSGID_PLURAL, COUNT)
           Marks MSGID as N__n() does, but in the context MSGCTXT.

EXPORTED VARIABLES
       The module exports several variables into your namespace:

       %__ A  tied  hash.   Its keys are your original messages, the values are
           their translations:

               my $title = "<h1>$__{'My Homepage'}</h1>";

           This is much better for your translation team than

               my $title = __"<h1>My Homepage</h1>";

           In the second case the HTML code will make it into  the  translation
           database  and  your translators have to be aware of HTML syntax when
           translating strings.

           Warning: Do not use this hash outside of double-quoted strings!  The
           code in the tied hash object relies on the correct  working  of  the
           function  caller() (see "perldoc -f caller"), and this function will
           report incorrect results if the tied hash value is the argument to a
           function from another package, for example:

             my $result = Other::Package::do_it ($__{'Some string'});

           The tied hash code will see "Other::Package" as the calling package,
           instead of your own package.   Consequently  it  will  look  up  the
           message  in  the wrong text domain.  There is no workaround for this
           bug.  Therefore:

           Never use the tied hash interpolated strings!

       $__ A reference to "%__", in case you prefer:

                my $title = "<h1>$__->{'My Homepage'}</h1>";

CLASS METHODS
       The following class methods are defined:

       options
           Returns a space-separated list of all '--keyword' and  all  '--flag'
           options  for  xgettext(1),  when extracting strings from Perl source
           files localized with Locale::TextDomain.

           The option should rather  be  called  xgettextDefaultOptions.   With
           regard to the typical use-case, a shorter name has been picked:

               xgettext `perl -MLocale::TextDomain -e 'print Locale::TextDomain->options'`

           See
           <https://www.gnu.org/software/gettext/manual/html_node/xgettext-Invocation.html>
           for  more  information  about  the  xgettext options '--keyword' and
           '--flag'.

           If you want to disable the use of the xgettext default keywords, you
           should pass an option '--keyword=""' to xgettext before the  options
           returned by this method.

           If  you doubt the usefulness of this method, check the output on the
           command-line:

               perl -MLocale::TextDomain -e 'print Locale::TextDomain->options'

           Nothing that you want to type yourself.

           This method was added in libintl-perl 1.28.

       keywords
           Returns a  space-separated  list  of  all  '--keyword'  options  for
           xgettext(1) so that all translatable strings are properly extracted.

           This method was added in libintl-perl 1.28.

       flags
           Returns   a   space-separated  list  of  all  '--flag'  options  for
           xgettext(1) so that extracted strings are properly flagged.

           This method was added in libintl-perl 1.28.

PERFORMANCE
       Message translation can be a  time-consuming  task.   Take  this  little
       example:

           1: use Locale::TextDomain ('my-domain');
           2: use POSIX (:locale_h);
           3:
           4: setlocale (LC_ALL, '');
           5: print __"Hello world!\n";

       This  will  usually  be quite fast, but in pathological cases it may run
       for several seconds.  A worst-case scenario would be a Chinese user at a
       terminal that understands the codeset Big5-HKSCS.  Your  translator  for
       Chinese  has  however  chosen  to encode the translations in the codeset
       EUC-TW.

       What will happen at run-time?  First, the library will search and load a
       (maybe large) message catalog for your textdomain 'my-domain'.  Then  it
       will  look up the translation for "Hello world!\n", it will find that it
       is encoded in EUC-TW.   Since  that  differs  from  the  output  codeset
       Big5-HKSCS,  it  will  first  load a conversion table containing several
       ten-thousands of codepoints for EUC-TW, then it does the same  with  the
       smaller,  but  still very large conversion table for Big5-HKSCS, it will
       convert the translation on the fly  from  EUC-TW  into  Big5-HKSCS,  and
       finally it will return the converted translation.

       A worst-case scenario but realistic.  And for these five lines of codes,
       there  is  not  much  you  can  do  to  make  it any faster.  You should
       understand, however, when the different steps will take place,  so  that
       you can arrange your code for it.

       You have learned in the section "DESCRIPTION" that line 1 is responsible
       for  locating your message database.  However, the use() will do nothing
       more  than  remembering  your  settings.   It  will   not   search   any
       directories, it will not load any catalogs or conversion tables.

       Somewhere   in   your   code   you   will   always   have   a   call  to
       POSIX::setlocale(), and the  performance  of  this  call  may  be  time-
       consuming,  depending  on  the  architecture  of  your  system.  On some
       systems, this will consume very little time,  on  others  it  will  only
       consume  a considerable amount of time for the first call, and on others
       it may always be time-consuming.  Since you cannot know, how setlocale()
       is implemented on the target system, you  should  reduce  the  calls  to
       setlocale() to a minimum.

       Line  5 requests the translation for your string.  Only now, the library
       will actually load the message  catalog,  and  only  now  will  it  load
       eventually  needed  conversion  tables.   And  from  now  on,  all  this
       information will be cached in memory.  This strategy is used  throughout
       libintl-perl,   and  you  may  describe  it  as  'load-on-first-access'.
       Getting the next translation will consume very little resources.

       However, although the translation retrieval is somewhat obfuscated by an
       operator-like function call, it is still a function call, and in fact it
       even involves a chain of function calls.   Consequently,  the  following
       example is probably bad practice:

           foreach (1 .. 100_000) {
               print __"Hello world!\n";
           }

       This  example introduces a lot of overhead into your program.  Better do
       this:

           my $string = __"Hello world!\n";
           foreach (1 .. 100_000) {
               print $string;
           }

       The translation will never change, there is no need to retrieve it  over
       and  over  again.   Although  libintl-perl  will  of  course  cache  the
       translation read from the file system, you can still avoid the  overhead
       for the function calls.

AUTHOR
       Copyright   (C)   2002-2017  Guido  Flohr  <http://www.guido-flohr.net/>
       (<mailto:guido.flohr@cantanea.com>),  all  rights  reserved.   See   the
       source code for details!code for details!

SEE ALSO
       Locale::Messages(3pm),   Locale::gettext_pp(3pm),  perl(1),  gettext(1),
       gettext(3)

perl v5.40.0                       2025-02-15              Locale...Domain(3pm)

Generated by dwww version 1.16 on Tue Dec 16 05:23:37 CET 2025.