L20n/HTML

From MozillaWiki
Jump to: navigation, search

Intro

This document is a tutorial on how to use L20n to localize your HTML web aplication.

Initial setup

We'll operate on an example of a very simple HTML5 document for the sake of this tutorial.

<html>
  <body>
    <header>
      <nav>
        <ul>
          <li>Page</li>
          <li>Discussion</li>
          <li>Edit</li>
        </ul>
      </nav>
    </header>
  </body>
</html>

As you can see, we have a simple header of a document here which is a navigation list with three links.

Make it localizable

The first step on the way to provide localization is to make it localizable. In order to do so we need to decouple content from the structure. It means that we have to take the content away from the document and store it in an external resource linked to the document via a <link /> tag.

In L20n framework, we store the localizable content in what we call Localizable Object Lists (LOL - sic!).

The last piece of the equation is to bind the HTML nodes to their respective localizable elements (called entities) by setting an l10n-id attribute on each node.

main.lol:

<page "Page">
<discussion  "Discussion">
<edit "Edit">

HTML:

<html>
  <head>
    <link rel="resource" type="intl/l20n" href="./locales/main.lol" />
  </head>
  <body>
    <header>
      <nav>
        <ul>
          <li l10n-id="page" />
          <li l10n-id="discussion" />
          <li l10n-id="edit" />
        </ul>
      </nav>
    </header>
  </body>
</html>



With this change, we now have our document localizable!

But we're not native yet!

At this moment, l20n is not a native technology so we need to add a intermediate step in form of an JS script that executes all L20n logic for the document.

HTML:

<html>
  <head>
    <script type="text/javascript;version=1.8" src="./js/l20n-xml.min.js"></script>

    <link rel="resource" type="intl/l20n" href="./locales/main.lol" />
  </head>
  <body>
    <header>
      <nav>
        <ul>
          <li l10n-id="page" />
          <li l10n-id="discussion" />
          <li l10n-id="edit" />
        </ul>
      </nav>
    </header>
  </body>
</html>


Pick a language

The goal of making the document localizable is to let user select a language in which he wants to see the content. For that to happen we need to provide multiple locales.

The first step is simple and it is to localize the main.lol document into another language. Let's pick German:

main-en-US.lol:

<page "Page">
<discussion  "Discussion">
<edit "Edit">

main-de.lol:

<page "???">
<discussion  "???">
<edit "???">

now we need to modify our HTML document to a) provide the list of available locales and b) instruct the document on where to find each locale file.

For the former, we will use standard <meta /> tag and list available locales there. For the latter we will modify the <link /> to cover the template.

HTML:

<html>
  <head>
    <meta http-equiv="Content-Language" Content="en-US, de">
    <script type="text/javascript;version=1.8" src="./js/l20n-xml.min.js"></script>

    <link rel="resource" type="intl/l20n" href="./locales/main-Template:Locale.lol" />
  </head>
  <body>
    <header>
      <nav>
        <ul>
          <li l10n-id="page" />
          <li l10n-id="discussion" />
          <li l10n-id="edit" />
        </ul>
      </nav>
    </header>
  </body>
</html>

Now, the l20n framework will take the locales available for the document and sort them according to the user preference. In result the best locale out of the available ones will be picked and loaded.

We now have a fully localized document! Whoa!

For more complex projects

What we showed so far is of course for the simplest cases. All of that can be provided programmatically:

HTML:

<html>
  <head>
    <script type="text/javascript;version=1.8" src="./js/l20n-xml.min.js"></script>

    <script type="text/javascript">
      var ctx = document.l10nCtx;
      ctx.settings.locales = ['en-US', 'de', 'it'];
      ctx.settings.schemes = [
        './locales/{{ locale }}/{{ app }}/{{ resource }}.lol
      ];
    </script>

    <link rel="resource" type="intl/l20n" href="./locales/main-{{ locale }}.lol" />
  </head>
  <body>
    <header>
      <nav>
        <ul>
          <li l10n-id="page" />
          <li l10n-id="discussion" />
          <li l10n-id="edit" />
        </ul>
      </nav>
    </header>
  </body>
</html>

or, for decoupled from the document and put into separate JSON manifest:

manifest.json:

{
  "schemes": [
    "./locales/{{ locale }}/{{ app }}/{{ resource }}.lol"
  ],
  "locales": {
    "supported": [
      "en-US",
      "de",
      "zh-CN"
    ],
    "source": "en-US"
  }
}

HTML:

<html>
  <head>
    <script type="text/javascript;version=1.8" src="./js/l20n-xml.min.js"></script>
 
    <span style="color: green"><link rel="manifest" type="intl/manifest" href="./locales/manifest.json"></span>
    <link rel="resource" type="intl/l20n" href="l10n:pontoon:core/editor" />
  </head>
  <body>
    <header>
      <nav>
        <ul>
          <li l10n-id="page" />
          <li l10n-id="discussion" />
          <li l10n-id="edit" />
        </ul>
      </nav>
    </header>
  </body>
</html>