MasonX-Resolver-Polyglot

 view release on metacpan or  search on metacpan

lib/MasonX/Resolver/Polyglot.pm  view on Meta::CPAN


Like our aformentioned English/Spanish site, we have an English index.html, and a Spanish index.html.es.  My site wants to provide the ability to choose the site language without mucking with the brower's language preference.
In my index.html, I have a "Spanish" link which links to "/es/index.html", and an "English" link in my index.html.es that links to "/index.html".  I make all other links in the site _relative_.

The effect this has is to propagate the /es/ prefix, consistantly overriding the browser's language preference until the user clicks on an absolute URL.

Polyglot now makes its language decision order array available through the Apache request pnotes() interface as an array ref.
If you call:

    my @langs   = @{$r->pnotes('POLYGLOT_LANGS')};

@langs will contain a ranked list of language preference.

It makes the language decision it made available by:

    my $lang    =   $r->pnotes('POLYGLOT_LANG');

And also, the original pre-language-stripped URI available like so:

    my $origuri =   $r->pnotes('POLYGLOT_URI')

=cut

package MasonX::Resolver::Polyglot;
$VERSION = q(0.95);

use strict;

# We need this, since our parent is embedded in the HTML::Mason::ApacheHandler file
use HTML::Mason::ApacheHandler;
use base qw(HTML::Mason::Resolver::File);

use HTML::Mason::Tools qw(paths_eq);
use Locale::Language qw(code2language);
use Locale::Country  qw(LOCALE_CODE_ALPHA_2 LOCALE_CODE_ALPHA_3 code2country);
use Apache::Constants;

my $DEBUG = 0;
# This is the name of the env variable that uri_override uses
my $POLYGLOT_LANG       = q(POLYGLOT_LANG);
my $PolyglotDefaultLang = q(PolyglotDefaultLang);
my $PolyglotDefaultURILang = q(PolyglotDefaultURILang);

sub new{
    my $class = shift;
    my $self = $class->SUPER::new(@_);
    $self->{default_lang} = lc Apache->request->dir_config($PolyglotDefaultLang);
    $self->{default_uri_lang} = lc Apache->request->dir_config($PolyglotDefaultURILang);
    return $self;
}    

sub get_info{
    my ($self, $path, $comp_root_key, $comp_root_path) = @_;
    
    # Is this already stored somewhere I can grab it?
    # I suspect this is wasteful.
    my $r = Apache->request;
    
    $DEBUG && $r->log_error(qq(URI:) . $r->uri . qq(, path: $path)); 
    $DEBUG && $r->log_error(qq(Header says: ), $r->header_in('Accept-Language'));
    # Get a ranked list of language prefs based on the Accept-Language and URI
    # everything in get_langs will need an $r
    $self->{r} = $r;
    my @langs = @{$self->get_langs(\$path)};
    $DEBUG && $r->log_error("Languages Accepted: ", join(",", @langs));
    delete $self->{r};
 
    # If we have a default language set, then "" gets spliced in 
    #  immediately after that language in the pref list.

    if($self->{default_lang}){
	for(0..$#langs){
	    if($langs[$_] eq $self->{default_lang}){
		splice(@langs, $_+1, 0, "");
	    }
	}
    }
	
    # No matter what, lastly look for the "pure" version
    push @langs, ""; # so we check a no extension lang last
    
     # CHECK to see if any exist in filesystem
    my $comp;

    # Make language order available through $r->pnotes
    my @POLYGLOT_LANGS = @langs;
    $r->pnotes('POLYGLOT_LANGS', \@POLYGLOT_LANGS);
    while(defined ($_ = shift @langs)){
        $DEBUG && $r->log_error(join("", $path, $_?('.', $_):""), $comp_root_key, $comp_root_path);
	if($comp = $self->SUPER::get_info(join("", $path, $_?('.', $_):""), $comp_root_key, $comp_root_path)){
	    $DEBUG && $r->log_error("picked '$_'");
	    return $comp;
	}
    }
    return;
}

=head1 METHODS

=over 4

=cut

# This resolver has a few new methods that it uses internally to determine what component to choose.
#=item get_langs
#This stores and returns a ranked list of components to try, using the URL and the client's language preferences to order them.  
#=cut

sub get_langs{
    my ($self, $path) = @_;
    # path is a scalar ref to the path that was fed to the resolver

    my %Accept;
    $self->_get_client_pref(\%Accept);
    # URL overrides browser
    $self->_get_env_pref(\%Accept);
    my @langs = sort { $Accept{$b}{q} <=> $Accept{$a}{q} } keys %Accept;
    $self->{langs} = \@langs;
}




( run in 1.251 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )