NAME

Locale::Maketext::Gettext::Functions - Functional interface to Locale::Maketext::Gettext

SYNOPSIS

use Locale::Maketext::Gettext::Functions;
bindtextdomain(DOMAIN, LOCALEDIR);
textdomain(DOMAIN);
get_handle("de");
print __("Hello, world!\n");

DESCRIPTION

Locale::Maketext::Gettext::Functions is a functional interface to Locale::Maketext::Gettext(3) (and Locale::Maketext(3)). It works exactly the GNU gettext way. It plays magic to Locale::Maketext(3) for you. No more localization class/subclasses and language handles are required at all.

The maketext and dmaketext functions attempt to translate a text string into the user's native language, by looking up the translation in an MO lexicon file.

FUNCTIONS

bindtextdomain(DOMAIN, LOCALEDIR)

Register a text domain with a locale directory. Returns LOCALEDIR itself. If LOCALEDIR is omitted, the registered locale directory of DOMAIN is returned. This method always success.

textdomain(DOMAIN)

Set the current text domain. Returns the DOMAIN itself. if DOMAIN is omitted, the current text domain is returned. This method always success.

get_handle(@languages)

Set the user's language. It searches for an available language in the provided @languages list. If @languages was not provided, it looks checks environment variable LANG, and HTTP_ACCEPT_LANGUAGE when running as CGI. Refer to Locale::Maketext(3) for the magic of the get_handle.

$message = maketext($key, @param...)

Attempts to translate a text string into the user's native language, by looking up the translation in an MO lexicon file. Refer to Locale::Maketext(3) for the maketext plural grammer.

$message = __($key, @param...)

A synonym to maketext(). This is a shortcut to maketext() so that it is cleaner when you employ maketext to your existing project.

($key, @param...) = N_($key, @param...)

Returns the original text untouched. This is to enable the text be catched with xgettext.

$message = dmaketext($domain, $key, @param...)

Temporarily switch to another text domain and attempts to translate a text string into the user's native language in that text domain.

encoding(ENCODING)

Set or retrieve the output encoding. The default is the same encoding as the gettext MO file.

key_encoding(ENCODING)

Specify the encoding used in your original text. The maketext method itself isn't multibyte-safe to the _AUTO lexicon. If you are using your native non-English language as your original text and you are having troubles like:

Unterminated bracket group, in:

Then, specify the key_encoding to the encoding of your original text. Returns the current setting.

encode_failure(CHECK)

Set the action when encode fails. This happens when the output text is out of the scope of your output encoding. For exmaple, output Chinese into US-ASCII. Refer to Encode(3) for the possible values of this CHECK. The default is FB_DEFAULT, which is a safe choice that never fails. But part of your text may be lost, since that is what FB_DEFAULT does. Returns the current setting.

die_for_lookup_failures(SHOULD_I_DIE)

Maketext dies for lookup failures, but GNU gettext never fails. By default Lexicon::Maketext::Gettext follows the GNU gettext behavior. But if you are Maketext-styled, or if you need a better control over the failures (like me :p), set this to 1. Returns the current setting.

reload_text()

Purges the MO text cache. By default MO files are cached after they are read and parsed from the disk, to reduce I/O and parsing overhead on busy sites. reload_text() purges this cache, so that updated MO files can take effect at run-time. This is used when your MO file is updated, but you cannot shutdown and restart the application. for example, when you are a co-hoster on a mod_perl-enabled Apache, or when your mod_perl-enabled Apache is too vital to be restarted for every update of your MO file, or if you are running a vital daemon, such as an X display server.

%Lexicon = read_mo($MOfile)

Read and parse the MO file. Returns the read %Lexicon. The returned lexicon is in its original encoding.

If you need the meta infomation of your MO file, parse the entry $Lexicon{""}. For example:

/^Content-Type: text\/plain; charset=(.*)$/im;
$encoding = $1;

NOTES

You can now add/remove languages/MO files at run-time. This is a major improvement over the original Locale::Maketext::Gettext(3) (and Locale::Maketext(3)). ^_*' This is done by registering localization classes with random IDs, so that the same text domain can be re-declared infinitely, whenever needed (language list changes, LOCALEDIR changes, etc.) This is not possible to the object-interface of Locale::Maketext::Gettext(3) (and Locale::Maketext(3)).

Language addition/removal takes effect only after bindtextdomain or textdomain is called. It has no effect on maketext calls. This keeps a basic sanity in the lifetime of a running script.

STORY

The idea is that: I finally realized that, no matter how hard I try, I can never get a never-failure maketext. A common wrapper like:

sub __ { return $LH->maketext(@_) };

always fails if $LH is not initialized yet. For this reason, maketext can hardly be employed in error handlers to output graceful error messages in the natural language of the user. So, I have to write something like this:

sub __ {
    $LH = MyPkg::L10N->get_handle if !defined $LH;
    return $LH->maketext(@_);
}

But what if get_handle itself fails? So, this becomes:

sub __ {
    $LH = MyPkg::L10N->get_handle if !defined $LH;
    $LH = _AUTO->get_handle if !defined $LH;
    return $LH->maketext(@_);
}
package _AUTO;
use base qw(Locale::Maketext);
package _AUTO::i_default;
use base qw(Locale::Maketext);
%Lexicon = ( "_AUTO" => 1 );

Ya, this works. But, if I always have to do this in my every application, why shouldn't I make a solution to the localization framework itself? This is a common problem to every localization projects. It should be solved at the localization framework level, but not at the application level.

Another reason is that: Programmers should be able to use maketext without the knowledge of object-oriented programming. A localization framework should be neat and simple. It should lower down its barrier, be friendly to the beginners, in order to encourage the use of localization and globalization. Apparently the current practice of Locale::Maketext(3) doesn't satisfy this request.

The third reason is: Since Locale::Maketext::Gettext(3) imports the lexicon from foreign sources, the class source file is left empty. It exists only to help the get_handle method looking for a proper language handle. Then, why not make it disappear, and be generated whenever needed? Why bother the programmers to put an empty class source file there?

How neat can we be?

imacat, 2003-04-29

BUGS

encoding, key_encoding, encode_failure and die_for_lookup_failures are not mod_perl-safe. These settings affect the whole process, including the following scripts it is going to run. This is the same as setlocale in POSIX(3). Always set them at the very beginning of your script if you are running under mod_perl. If you don't like it, use the object-oriented Locale::Maketext::Gettext(3) instead. Suggestions or solutions are welcome.

Smart translation between Traditional Chinese/Simplified Chinese, like what GNU gettext does, is not available yet. Suggestions or solutions are welcome.

SEE ALSO

Locale::Maketext(3), Locale::Maketext::TPJ13(3), Locale::Maketext::Gettext(3), bindtextdomain(3), textdomain(3). Also, please refer to the official GNU gettext manual at http://www.gnu.org/manual/gettext/.

AUTHOR

imacat <imacat@mail.imacat.idv.tw>

COPYRIGHT

Copyright (c) 2003 imacat. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.