Well... My handler is pretty ugly at this point and I am sure quite
crufty compared with the current state of the art, also there is a lot
of custom code mixed in that is not relevant or interesting to you all.
However, I can post some of the relevant snippets:
BEGIN {
my $cur_locale = undef;
sub set_unix_locale {
my $locale = shift || "C";
return $cur_locale if (defined $cur_locale and $cur_locale eq
$locale);
$cur_locale = POSIX::setlocale( &POSIX::LC_ALL, $locale );
return $cur_locale;
}
}
# Process the files
sub preprocess_i18n {
my ($text, $loc) = @_;
my $escape = 1;
# See what file we are in by some nasty black magic. We need
# to dig back through the caller's arguments until we find a
# sub call to parse_component() with the name script_file.
# Unfortunately the name of the current component is not stored
# anywhere else during parsing.
my $c = 0; # How far back to look
while (1) {
my @caller = do { package DB; caller($c++) };
last unless @caller;
if ($caller[3] eq 'HTML::Mason::Parser::parse_component') {
my ($self, %args) = @DB::args;
# If we are in js file, turn off escaping.
if (exists $args{script_file}) {
if ($args{script_file} =~ /\.js$/i) {
$escape = 0;
print STDERR "Skipped $args{script_file}\n";
}
last;
}
}
}
# And to the translate
translate_strings($text, $escape);
return 1;
}
my %locale_i18n_settings = ();
foreach my $loc (keys %handlers) {
# Sanity check the locales to ensure that they are valid
$ENV{LC_ALL} = $loc;
my $set_locale = set_unix_locale($loc);
croak "Unable to set locale '$loc'."
unless defined $set_locale and $set_locale eq $loc;
# Reset the locale to C so we don't get messed up
$ENV{LC_ALL} = 'C';
set_unix_locale('C');
# Check the locale settings
my $send_i18n = $_support_i18n;
unless ($loc =~ /^(C|POSIX|en(\.UTF-8)?|en_.*)$/) {
# See if we need to send UTF-8 to the browser
unless ($_support_i18n) {
#print STDERR "Internationalization support disabled but
locale '$loc' requires it... Forcing it on for that locale.\n";
$send_i18n = 1;
}
# Print a warning if we are not in a UTF-8 locale
unless ($loc =~ /\.UTF-8/) {
print STDERR "Warning: Locale '$loc' might not support
UTF-8.\n";
}
}
$locale_i18n_settings{$loc} =
{send_i18n => $send_i18n,
};
# Create Mason objects
my $parser = HTML::Mason::Compiler::ToObject->new
(%parser_opts,
preprocess => sub {preprocess_i18n(@_, $loc)},
preamble => "set_unix_locale('$loc');\n",
postamble => "set_unix_locale('C');\n",
);
my $interp = HTML::Mason::Interp->new
(%interp_opts,
compiler => $parser,
compiler_class => "HTML::Mason::Compiler::ToObject",
data_dir => "$_datadir/$loc",
error_mode => 'output',
);
$interp->set_global(basedir => $_basedir);
$interp->set_global(baseurl => $_baseurl);
...
my $handler = HTML::Mason::ApacheHandler->new
( %handler_opts,
interp => $interp,
apache_status_title => "$_module Status (locale $loc)",
);
$handlers{$loc} = $handler;
# Activate the following if running httpd as root (the normal case).
# Resets ownership of all files created by Mason at startup. Change
# these to match your server's 'User' and 'Group'.
if ($> == 0 and !$IsWin32) {
chown(scalar(getpwnam "brix_apache_user"),
scalar(getgrnam "brix_apache_group"),
$interp->files_written);
}
}
...
sub handler {
my ($r, $username, $password) = @_;
# Set the locale to a known state (and we reset it before any return
below)
$ENV{LC_ALL} = "C";
set_unix_locale("C");
# Do whatever you need to do to set up the handler and find the
appropriate locale
...
# Work out whether we are sending UTF-8 for this locale
my $use_i18n = $locale_i18n_settings{$locale}{send_i18n};
$r->content_type('text/html; charset=utf-8')
if $reset_charset and $use_i18n;
# Pass the request off to the correct handler
my $handler = $handlers{$locale};
die "Missing handler for locale '$locale'."
unless defined $handler;
# Set the value of support_i18n for this call
$handler->interp()->set_global(support_i18n => $use_i18n);
# Set up the locale environment (See catopen(3C) for details)
$ENV{'NLSPATH'} = "$_basedir/Catalogs/$locale".$_base_nlspath;
$ENV{'LC_ALL'} = $locale;
# And handle the request
my $status = $handler->handle_request($r);
# Cleanup code goes here (session, dbh, etc.)
...
$ENV{LC_ALL} = "C";
set_unix_locale("C");
return wantarray ? ($status, $OUTBUFFER) : $status;
}
-ben
> -----Original Message-----
> From: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED] On Behalf
> Of Kovacs Baldvin
> Sent: Tuesday, January 09, 2007 9:42 AM
> To: [email protected]
> Subject: Re: [Mason] l10n efficiency
>
> > The idea about letting the Mason parser produce separate
> files based on
> > language may seem nice, but I wonder if the gain in
> computation is really
> > that substantial. Especially when there are queries to
> remote DBs, reading
>
> Yes, I know. However, making lots of hash lookups in runtime just
> because we don't take the effort to implement translation
> earlier in the
> chain, where it belongs to, now that's ugly. And since I'm just about
> deciding what system to use, this question can be posed now. If I were
> after the internationalization effort, I'd probably never do
> any steps
> for a (much?) less then 1 percent saving.
>
> > sessions, multiple components, etc. making the translation
> overhead a small
> > part of the total cost, my gut feeling is that this is
> better handled with
> > things like caching (Mason component caching) or
> network/browser caching
> > (with all its pitfalls).
>
> Considering that result pages of a webapp are almost never
> cacheable, I don't
> see any way to introduce caching to the problem of translation.
>
> On the level of compiled mason components however, my suggestion of
> localized .obj files trades some compile time and cache size for some
> running speed, so in this meaning: yes, it can be handled
> with component
> caching, which does not mead my suggestion doesn't have validity.
>
> > Has anybody measured this once ? I guess not :-)
>
> Hey, at least I found something I can be first in :-). I think I'll
> look into the solution that Ben told about, I hope he gives some code.
> I'll check it out if it is similar than the localized .obj files idea
>
> (He talks about separate compilers for locales, I didn't
> think that,
> I was thinking about tweaking the compiler itself.
> However, maybe his
> solution is even better.)
>
> If so, then I'll do some measurements...
>
> Baldvin
>
> --------------------------------------------------------------
> -----------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the
> chance to share your
> opinions on IT & business topics through brief surveys - and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge
> &CID=DEVDEV
> _______________________________________________
> Mason-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/mason-users
>
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Mason-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mason-users