Skip to content
taiwen edited this page Mar 14, 2013 · 1 revision

Pi I18n Guide

Contents

  • Introduction
  • Using translators in project
  • Creating the csv file for translators
  • Localizing form validator messages
  • Localizing upload validator messages

Introduction

The Pi may have users come from different countries, some users may have difficult to operate this application because it is write by English as default. Fortunately, Pi provides users a translation mechanism, users can translate the language into their local language. This guide will introduce how to use translator in Pi.

In Pi, the locale folder is used to store translator files. You may find that the locale folder is placed in three different places, which are usr/locale, module/{module name}/locale and theme/{theme name}/locale.

  • usr/locale

Files in this folder allow users to define default translator if there is no matched translator in the module package. Folders in locale named such as en, zh-CN to indicate language of different countries. These folders at least should contain one file named main.csv.

Its file structure is like this:

locale
    en
        main.csv
        ...
    zh-CN
        main.csv
        ...
    ... 
  • module/locale

Translators in this folder have the higher priority than that of usr/locale, the translators in this folder will be used first if it is defined. This folder has the same file structure as usr/locale.

  • theme/locale

Using translators in project

Pi provides users some methods for translation, which are __() and _e(). The first method only translates a string, and the later will output the translation result to browser. The parameter type of these methods is string.

For example:

echo __('Hello world!');
_e('Hello world');

NOTE: These two methods can be used in everywhere of your project.

The Pi application has loaded main.csv as default, if user want to use their own translate file, for example, a user add a translator in the front.csv in your module such as:

Test,Test application

If you want to realize this translator, you should first load the front.csv resource in the relating template:

<?php $this->I18nModule('front'); ?>

Repeating to add the same code if you want to add more translate files.

Creating the csv file for translators

As mentioned above, users should create csv files in the locale folder for translation.

Hello world,HELLO WORLD
Test,TEST
...

And then the 'Hello world' string will be translated into 'HELLO WORLD', and 'Test' will be translated into 'TEST'.

Localizing form validator messages

Sometimes users want to output error messages when the input form is invalid, but the error messages are operated by Zend\Validator\AbstractValidator handler, users can not get the error messages of their own language. In this section, we will introduce how to localizing validator messages of Pi.

There mainly have two method:

  1. Using syntactic sugar -- __();
  2. Using Pi\I18n\Translator\Translator handler.

Using systactic sugar

Changing the message templates

The method is the same as that we introduced previous section, which is simplying surround error message with __() method. This method can be done because of the Zend\Validator\AbstractValidator handler provides us a method to operate error message templates.

Supposes we create a TestFilter.php file, and add two validators for username input. The validators are StringTrim and Regex, and the code is given as follows:

namespace Module\Test\Form;

use Pi;
use Zend\InputFilter\InputFilter;
use Zend\Validator\StringLength;
use Zend\Valicator\Regex;

class TestFilter extends InputFilter
{
    public function __construct()
    {
        $this->add(array(
            'name'          => 'username',
            'required'      => true,
            'validators'    => array(
                array(
                    'name'         => 'Regex',
                    'options'      => array(
                        'pattern'       => '/^[a-zA-Z0-9][a-zA-Z0-9-_]{0,24}$/',
                        'messages'      => array(
                            Regex::NOT_MATCH => __("The input does not match against pattern '%pattern%'"),
                        ),
                    ), 
                ),
                new StringLength(array(
                    'min'          => '4',
                    'max'          => '25',
                    'messages' => array(
                        StringLength::TOO_SHORT => __("The input is less than %min% characters long"),
                        StringLength::TOO_LONG  => __("The input is more than %max% characters long"),
                    ),
                )),
            ),
        ));
        
        ...
    }
}

In the code, a messages field is used, that will tell the Zend\Validator\AbstractValidator class to call the setMessages method, and replace the message templates with given translated messages.

The keys Regex::NOT_MATCH, StringLength::TOO_SHORT and StringLength::TOO_LONG must be as same as that define in Regex and StringLength classes.

Changing the error messages

The method above is change the message templates of validator handler, this code must be add before isValid() is called. But some other validator such as NotEmpty (Create according to the required field of above code) is create during isValid method is call, therefore, method of changing the message templates is useless.

Another method is to change the error message of Zend\View\Helper\Element class.

The following code must be add after isValid method in action method which processes forms:

if(!$form->isValid()) {
    ...
    $element  = $form->get('username');
    $messages = $element->getMessages();
    if (isset($messages[\Zend\Validator\NotEmpty::IS_EMPTY])) {
        $messages[\Zend\Validator\NotEmpty::IS_EMPTY] = __("Value is required and can't be empty");
        $element->setMessages($messages);
    }
    ...
    return;
}

After add translation code, remember to add translation content in csv file.

"The input does not match against pattern '%pattern%'", "用户名格式不正确"
"The input is less than %min% characters long", "用户名少于%min%个字符"
Value is required and can't be empty, 表单不能为空

Using translator handler

This method is more simple, beacuse the Zend\Validator\AbstractValidator class use static variable to store translator handler, the only thing we do is add the system translator to AbstractValidator class before isValid method is called.

$translator = Pi::service('i18n')->translator;
\Zend\Validator\AbstractValidator::setDefaultTranslator($translator);
$this->add(array(
    'name'          => 'username',
    'required'      => true,
    ...
));

Then a translation content is also need to add.

Localizing upload validator messages

Pi provides users a Pi\File\Transfer\Upload to process uploaded files, if errors occur, error messages will also generate by the class, therefore, we need to add extro code for localizing.

There also have two methods to localize error messages as same as that we introduce above.

Adding respectively

This method mainly finds the validator variable and then changes the template messages with localized messages.

$upload = new \Pi\File\Transfer\Upload();
$upload->setDestination($path)
        ->setRename($rename)
        ->setExtension($ext)
        ->setSize($size);

$messages = array(
    Size::TOO_BIG   => __("Maximum allowed size for file '%value%' is '%max%' but '%size%' detected"),
);
$upload->getAdapter()
        ->getValidator('Zend\Validator\File\Size')
        ->setMessages($messages);

Using translator handler

This method only add translator handler to AbstractValidator handler before isValid:

$translator = Pi::service('i18n')->translator;
\Zend\Validator\AbstractValidator::setDefaultTranslator($translator);

$upload = new \Pi\File\Transfer\Upload();
$upload->setDestination($path)
        ->setRename($rename)
        ->setExtension($ext)
        ->setSize($size);

if ($upload->isValid()) {
    ...
}