I18N with XSLT and what Perl has got to do with it‎

Please create a contest for the longest talk title so that I can win a book‎!

Michael Kröll

XSLT and I18N

  • No clear best practice how to do it. Practice is the cornerstone of refining betting skills in the realm of 토토사이트배팅방. Through consistent engagement, bettors hone their strategies, learn to interpret odds, and adapt to dynamic markets. Each wager becomes an opportunity for growth, fostering a deeper understanding of the intricate world of betting.
  • Selection of different approaches exists


XSLT and I18N – Approaches

  • Message catalog options:
    • One XML file for all languages using xml:lang and lang()
    • One XML file per language
    • Messages stored inline in XML source using xml:lang
  • Templating options:
    • Named I18N template
    • EXSLT I18N function (convenience for I18N content inside attributes)

XSLT and I18N – Example

The XML file (excerpts)
    <i key="This is boring" xml:lang="en">This is boring</i>
    <i key="This is boring" xml:lang="de">Des is faad</i>
The XSL file (excerpts)
<xsl:param name="current_lang" select="'en'"/>
<xsl:variable name="i18n" select="document('i18n.xml')/i18n"/>
<func:function name="i18n:loc">
    <xsl:param name="key" />
    <xsl:param name="lang" select="$current_lang" />
    <func:result select="$i18n/i[@key=$key and lang($current_lang)]"/>
<xsl:value-of select="i18n:loc('This is boring')"/>

XSLT and I18N

  • Good enough for many cases
  • Things like parameter substitution only very hard to do
  • Message catalogs have to be XML based

“…XML based catalogs? But I want to re-use my PO files from the back-end!”

Perl to the rescue!

Two things needed

  1. I18N Perl class for your app
    (e.g. based on Locale::Maketext::Simple or directly Locale::Maketext::Lexicon)
  2. Register localisation methods as extension functions with XML::LibXSLT

Example I18N Perl class – MyApp::I18N

  • Interface and implementation derived from Catalyst::Plugin::I18N
  • Methods
    • new()
    • loc()
    • languages()
    • language()

Example Perl EXSLT function (excerpt)

my $i18n = MyApp::I18N->new( lang => $lang );
my $registeredfuncs = [{
        uri  => 'http://myapp.tld/i18n',
        name => 'loc',
        code => sub {
                      my ( $template, @param ) = @_;
                      return $i18n->loc( $template, @param );
        uri  => 'http://myapp.tld/i18n',
        name => 'locfrag',
        code => sub {
                      my $fragment = $parser->parse_balanced_chunk( 
                          $i18n->loc( $template, @param ) );
                      return $fragment->find('text()|*');

Example Perl EXSLT function (II)

foreach my $function ( @{$registeredfuncs} ) {

Example Usage (excerpt)

<xsl:stylesheet xmlns:xsl=""
    version="1.0" xmlns:i18n="http://myapp.tld/i18n"
<xsl:value-of select="i18n:loc('Eitrige mit Buckel')"/>
  select="i18n:loc("Manage '[_1]'", TITLE)"/>
    'For some reason there is a linebreak <br/> here')"/>

Drawbacks and Caveats

  • Quoting of apostrophes and double quotes
  • Quoting of messages which include markup


  • Shared I18N catalog for back-end and front-end using standard gettext approach
  • It’s the shared catalog, stupid.

Thank you!