Locale::gettext
version 1.05

This is a perl5 module quickly written to gain access to
the C library functions for internatialization. They
work just like the C versions.

As of version 1.04, an object oriented interface more
suitable to native Perl programs is available.

Locale::gettext is Copyright 1996..2005 by Phillip Vandry
<vandry@TZoNE.ORG>. All rights reserved.

This library is free software; you may distribute under the terms
of either the GNU General Public License or the Artistic License, as
specified in the Perl README file.

Changes
-------

1.05	Bugfix: [cpan #13042] useless #ifdef should be #if
	Bugfix: [cpan #13044] make test fails when using POSIX locale

1.04	Add several functions provided by the GNU gettext library
	Create object oriented interface

1.03	Fix error in README file

1.02	Include a License

1.01	Changed from "gettext" to "Locale::gettext" (i.e.
	moved under Locale::) on the advice of several
	people

	Small "lint" fix from schwern@starmedia.net

1.00	Initial version

TODO
----

A TIEHASH interface

Here's a quick tutorial.
-----------------------

Note that your vendor's implementation of these functions
may be a bit different, but I think that in general these
are quite standard POSIX functions.

Phillip Vandry <vandry@TZoNE.ORG>
Mlink Internet <http://www.Mlink.NET>
July 1996

INTERNATIONALIZING YOUR PROGRAM

Step 1
------

If you've already written your code, you need to
wrap the gettext() function around all of the
text strings. Needless to say, this is much easier if
you do it while you write.

# create object for oo interface
my $d = Locale::gettext->domain("my_program");

print "Welcome to my program\n";

# oo
print $d->get("Welcome to my program"), "\n";

# traditional
print gettext("Welcome to my program"), "\n";

Note that you probably don't want to include that newline
in the gettext() call, nor any formatting codes such as
HTML tags. The argument to gettext() is the text string
in the default language or locale. This is known as the
C locale and should probably be usually English.

Step 2
------

Do the apropriate initializations at the beginning of your
program:

#
use POSIX;     # for setlocale()
use Locale::gettext;
#
# The following statement initializes the locale handling
# code in the C library. Normally, it causes it to read
# in the environment variables that determine the current
# locale.
#
# The first parameter is the category you would
# like to initialize locale information for. You can use
# LC_ALL for this, which will set locale information for
# all categories, including LC_CTYPE, LC_TIME, LC_NUMERIC,
# etc..
#
# I recommend that you set only LC_MESSAGES (text strings)
# or LC_CTYPE (character sets) and LC_TIME (time
# conventions) too at most. You may find that if you set
# LC_NUMERIC or some other categories, you will start
# outputting decimal numbers with strange thousand separators
# and decimal points and they will be unparseable in
# other countries.
#
# The second parameter is the locale name. If it is an
# empty string, then this information will be fetched from
# environment variables.
#
# Note that setlocale() will cause every part of your
# program to start operating in the new, non default (C)
# locale, including C library functions. So don't be
# surprised if POSIX::ctime returns "Montag, 22. Juli 1996,
# 12:08:25 Uhr EDT" instead of "Mon Jul 22 12:08:25 EDT 1996"
# If you set LC_TIME or LC_ALL using setlocale().
#
setlocale(LC_MESSAGES, "");
#
# Decide on a unique identifier that will distinguish your
# program's text strings in the LC_MESSAGES database. This
# would usually be the name of your program
#
# By default, locale information is found in OS dependant
# system directories such as /usr/lib/locale, or any directory
# found in the $PATH-like environment variable $NLSPATH.
# I recommend that you do _not_ install files in /usr. If
# your program is installed in a directory tree such as
# /opt/my_package_name/{bin,man,lib,etc}, then you could
# use /opt/my_package_name/locale to store locale information
# specific to your program, or you could put in somewhere
# in /usr/local/lib.
#
# Wherever you put it, if it is not one of the default
# directories, you will need to call bindtextdomain() to
# tell the library where to find your files. The first
# parameter is your database's identifier that you chose
# above.
#
# oo interface:

my $d = Locale::gettext->domain("my_domain");
$d->dir("/opt/my_package_name/locale");

# traditional interface:
bindtextdomain("my_domain", "/opt/my_package_name/locale");
textdomain("my_domain");

# That's it for the initializations

Step 3
------

Test to see if your program still works after all these mods :-)

Step 4
------

TRANSLATE!

Read msgfmt(1) for details on this. Basically, for each locale
other than the default, you need to create a file like this:
(Note: I do not speak German, I'm making an attempt here :-)
Call this file with the .po extension.

--BEGIN
domain "my_domain"

msgid  "Welcome to my program"
msgstr "Willkommen in mein Program"

msgid  "Help"
msgstr "Hilfe"
--END

The "msgid" parameter must match exactly the argument to the
gettext() function, and "msgstr" is the corresponding translation.

You can use the xgettext(1) utility to initially construct this
file from all of the gettext() calls in your source code. It was
designed for C but it works OK with perl.

Step 5
------

Compile the .po file

$ msgfmt my_file.po

This will create a file called my_domain.mo (default messages.mo)
which you should place in the <locale>/LC_MESSAGES/my_domain.mo
subdirectory of either a system default directory, a directory
in $NLSPATH, or the directory argument to bindtextdomain().
Replace <locale> with the name of the locale for which this file
is created.

For example:

$ mkdir -p /opt/my_package/locale/de/LC_MESSAGES
$ mkdir -p /opt/my_package/locale/fr/LC_MESSAGES
$ cd /path/to/my/source/code
$ cd de
$ msgfmt my_domain.po
$ mv my_domain.mo /opt/my_package/locale/de/LC_MESSAGES
$ cd ../fr
$ msgfmt my_domain.po
$ mv my_domain.mo /opt/my_package/locale/fr/LC_MESSAGES

Step 6
------

Test it out

$ my_program
Welcome to my program
$ LANG=fr my_program
Bienvenue à mon programme
$ LANG=de my_program
Willkommen in mein Program

(Or, set only the messages category instead of the whole locale)

$ LC_MESSAGES=fr
$ export LC_MESSAGES
$ my_program
Bienvenue à mon programme
