MasonX::Resolver::Polyglot - Component path resolver for easy internationalization


MasonX::Resolver::Polyglot - Component path resolver for easy internationalization


In your http.conf:

    PerlInitHandler MasonX::Resolver::Polyglot
    <Directory /var/www/html>
     PerlSetVar PolyglotDefaultLang en
     PerlSetVar PolyglotDefaultURILang en
     PerlAddVar MasonDataDir "/var/www/mason"
     PerlAddVar MasonCompRoot "/var/www/html"
     <FilesMatch "^..$|\.html(\...)?$">
           SetHandler perl-script
           PerlSetVar MasonResolverClass MasonX::Resolver::Polyglot
           PerlHandler HTML::Mason::ApacheHandler

Or, in your Mason guts:

  my $resolver = MasonX::Resolver::Polyglot->new( comp_root => '/var/www/mason' );
  my $info = $resolver->get_info('/some/comp.html');
  my $comp_root = $resolver->comp_root;


PolyglotDefaultLang sets the fall back language. If unset, Polyglot will fall back on a file with no suffix (foo.html).
PolyglotDefaultURILang overrides language selection based upon Language-Accept. It is equivalent to prefixing the url with a language code (


This HTML::Mason::Resolver::File::ApacheHandler subclass enables Mason to determine the client's language preference and find the best matching component to fulfill it.

This allows a web designer to provide structure in language independant components, and confine language-centric HTML to other components that the top level pages use.

Components are labeled by suffix.

Examples: index.html - language independant component. Either last try component (if no other languages are acceptable) or the default language (if PolyglotDefaultLang is set). - Spanish component. If a browser's Language-Accept describes Spanish as more preferable than English, requests for index.html will return this component.

There is nothing magic about the html suffix; these do not have to be top level components. Let us suppose that index.html has a component called ``menubar'' which has text or image buttons of the site map. We may write the following components: menubar - the English version (we have set PolyglotDefaultLang to ``en'') menubar.en-us - the American English version - the French version - the Italian version

The code in index.html just calls ``menubar'' normally, and the resolver will pick the ``right'' component, ultimately falling back on the unsuffixed version if it can't find a better match.

There are really two pieces to Polyglot. The Mason resolver piece is a child of HTML::Mason::Resolver::File::ApacheHandler and compares the Language-Accept preferences a web client presents with what is available on the filesystem, and finds the best match.

The other piece is the PerlInitHandler which scans (and potentially alters) the URL for a leading language code. The effect this has is to override all preferences. If, for some reason, you want to peek at the URI that actually was typed in before Polyglot ate the language code, it is stashed away in $r->pnotes('POLYGLOT_URI').

Like our aformentioned English/Spanish site, we have an English index.html, and a Spanish 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 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')


This has an alias as handler so you don't have to specify the method if you set MasonX::Resolver::Polyglot as a PerlInitHandler.

This examines the URL for a leading, lowercase language tag of the format langcode<-sublangcode> (en, en-us, es etc.).

If it finds one, it will give that language the highest precidence, and MODIFY THE URL, REMOVING THE LANGUAGE TAG.

The upshot of this is that regardless of the browser's Accept-Language preference, it can be overriden using the URL. - gives me an English page - forces it to give me the Spanish page (if it exists)




Thanks to Dorian Taylor <> for his nice Accept-Language code.


Benjamin H Kram <>