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: mason-users@lists.sourceforge.net
> 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
> Mason-users@lists.sourceforge.net
> 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
Mason-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mason-users

Reply via email to