Localization

The Enano localization API allows translated interfaces to be built. Enano language strings are designed to be usable across both PHP and Javascript, so you can build your interfaces in different languages without writing two sets of strings.

Language structure

In Enano, languages are identified by their numeric identifier or their three-letter ISO 639-3 code. Numeric identifiers are different across every site, while ISO 639 codes are always the same. Thus, to deal with multiple languages in plugins, use the ISO 639 code. A list of ISO 639-3 codes is available. The code for English is "eng".

Strings must be imported into the database and caches before the Enano API is able to access them. On the disk, they are stored in JSON format. JSON language files can be imported using the method $lang->import().

The Language class

Languages are handled by the Language class, which should be instanciated once for each language to be loaded. During Enano initialization, the session manager initializes a global instance, $lang, based on the user's language preference. $lang is available at the session_started hook and at every point thereafter; you can check to see if it is initializes using is_object($GLOBALS['lang']). It is not necessary to localize all strings, only the ones a user will see as part of general operation (but do take care to localize all form validation errors and other such messages). It is generally a good practice to avoid localizing critical errors.

Language file structure

Language strings are categorized for easier location and organization. The Enano core contains 50 categories of strings. Any plugin can both extend the core's string categories and add its own.

Strings are retrieved in the format <category>_<id>. As such, categories cannot contain underscores or any other characters outside of a-z and 0-9. The method for retrieving strings is $lang->get().

File format

Language files are written in JSON with a couple of alternate syntax options available for readability:

  • In-line comments (// foo) may be included
  • String keys do not need to be quoted (foo: 'bar' instead of 'foo' : 'bar').
  • Any text before the first opening curly brace ({) and after the last closing curly brace (}) is ignored. This allows for block comments before the strings start.

Outside of those two exceptions, language files must be standards-compliant. Internally, Enano corrects the JSON to standards-compliance before parsing it.

Files must consist of a single object containing two members: categories (an array) and strings (an object). categories must simply be a list of all the members of strings. The "meta" category should contain only the localized names of other categories. Each plugin should provide a meta category and localized category names.

{
  categories: ['meta', 'myplugin'],
  strings: {
    meta: {
      myplugin: 'My plugin'
    },
    myplugin: {
      foo: 'Foo string',
      bar: 'Bar string',
      baz: 'Baz string',
      quux: 'Quux string with %variable% in it',
      quux_safe: 'Quux string with %variable|htmlsafe% in it',
      msg_hello: 'Hello, %username|htmlsafe%!',
      site_name: 'Welcome to %config.site_name|htmlsafe%.'
    }
  }
}

Variables and formatted strings

Strings may contain variables in the form of %variable%. Variables are assigned with the get() call via an associative array in the second parameter.

<?php
// Tell the user hello in their local language
echo $lang->get('myplugin_msg_hello', array('username' => $session->username));
?>

You may retrieve a value from the site configuration directly using the variable format %config.item_name%. It is also possible to dynamically embed another string from the same language using the format %this.category_stringid

Filtering values

You may pass a variable through a filter using the syntax %variable|filter%. Multiple filters may be used. Enano includes the following filters:

  • htmlsafe - passes the variable through htmlspecialchars()
  • urlencode - self-explanatory
  • rawurlencode - self-explanatory

You may register a filter using the method $lang->register_filter().

Javascript API

All language strings are accessible through Javascript in addition to PHP. Variable functionality is also present, but filtering is not available in Javascript. You must load the component l10n before fetching any strings using the Javascript API.

Just like the PHP version, the Javascript API uses the method $lang.get() to retrieve strings and parse variables.

load_component('l10n'); // Only need to do this once
var string = prompt('What would you like to say?');
alert($lang.get('myplugin_quux', { variable: string }));

Categories: (Uncategorized)