Sunday
16
May
2010

Routing translations

Hy fellows,

sometimes a message can not be translated. In this case the original message id will be returned.
But it could be useful to return the translation for another language instead of the message id.

This is called “translation routing” and supported with the next minor release.

Let’s see an example:

$translate = new Zend_Translate(array(
    'adapter' => Zend_Translate::AN_ARRAY,
    'content' => $mytranslations,
    'route' => array('de' => 'en')
));

Now we have a message id of “HEAD”… a user requesting german would expect to get “Meine Überschrift”.
But when there is no translation for this message id he would see “HEAD”.

With the set routing Zend_Translate will internally change the language to the new route and try to translate the message id with the other language.
So he would get “My Header” instead “HEAD”.

This feature seems to solve all problems for those who have no complete translations. But there are also some negs which should be thought of:
1.) You can not route a language to two others.
2.) When Zend_Translate is routing you will still get an “untranslated notice” for every message id and language which can not be translated
3.) When you route users to a language which they don’t understand you are irritating them

You can also build a translation chain by routing from several languages in a sort of priority:
Let’s see an example:

$translate = new Zend_Translate(array(
    'adapter' => Zend_Translate::AN_ARRAY,
    'content' => $mytranslations,
    'route' => array('de' => 'en', 'en' => 'fr')
));

This creates the following chain:

GERMAN => ENGLISH => FRENCH

So german could return english when there is no translation. And when there is no translation for english it would even return french.

Now you could say: Let’s break translation and add a circle routing, something like this:

$translate = new Zend_Translate(array(
    'adapter' => Zend_Translate::AN_ARRAY,
    'content' => $mytranslations,
    'route' => array('de' => 'en', 'en' => 'de')
));
GERMAN => ENGLISH => GERMAN

What now happens is that german returns english, and english returns german when there is no translation. But when there is no english translation it does not try to return german again, instead it returns the message id itself.

So you will always have a translation.

Further informations can be retrieved within the official mailing lists and within IRC.
I hope you find this feature useful. More to come soon…

Greetings
Thomas Weidner
I18N Team Leader, Zend Framework

Zend Framework Advisory Board Member
Zend Certified Engineer for Zend Framework

Back to top
Sunday
2
May
2010

Validation of two values or how to proove identical-ness

Hy interested ones,

today I integrated two improvements for Zend_Validate_Identical.

Zend_Validate_Identical is a validator which enables you to check if two values are identical.
Values means in this case string, integers, floats, or even objects.

A manual validation would look like this:

$valid = new Zend_Validate_Identical(array('token' => '1234'));
	
if ($valid->isValid($input)) {
    // let's go on
} else {
    // oops... not valid
}

Simple as is…

Now, when $input is the string “1234” we will get true. When it differs we will get false. This means even if we have a integer “1234” the validation will fail. The reason behind this behaviour is that Zend_Validate_Identical does a strict validation including the type of the input.

But sometimes it is wished and necessary to validate only the content regardless of it’s type.
Zend_Validate_Identical supports now also non-strict validation. See the following example:

$valid = new Zend_Validate_Identical(
    array('token' => '1234', 'strict' => false)
);
	
if ($valid->isValid($input)) {
    // let's go on
} else {
    // oops... not valid
}

As you can see the above example is nearly identical to the first example with one difference. We defined the property strict to be false. By using this option we said Zend_Validate_Identical to use non-strict validation.

In this case, when $input is a integer “1234” we will also get true in return and also when it’s a float “1234”.

Now what to do when you want to validate if two form elements are identical. Seems tricky as Zend_Validate_Identical has no connection to Zend_Form, and it would not know which two elements you want to validate.

Easy as is, you can now give the elements name as token which holds the token to validate against. What does this mean? Let’s see a little example:

<?php
error_reporting(E_ALL|E_STRICT);
ini_set('include_path',ini_get('include_path').PATH_SEPARATOR.'../library');
require_once('Zend/Loader/Autoloader.php');
$loader = Zend_Loader_Autoloader::getInstance();
print "<pre>";
	
$request = new Zend_Controller_Request_Http();
	
// setup the form
$form = new Zend_Form();
$form->setMethod(Zend_Form::METHOD_POST)
$form->addElement('password', 'password1');
$form->addElement('password', 'password2', array(
    'validators' => array(
        array('identical', false, array('token' => 'password1'))
    )
));
$form->addElement('submit', 'submit');
	
// check the form
if($request->isPost()) {
    $formData = $request->getPost();
    if($form->isValid($formData)) {
        $form->getValues();
        echo "FORM VALID";
    } else {
        print "\nVALIDATION FAILURE:";
        print_r($form->getMessages());
    }
}
print "</pre>";
?>
<html>
<head>
<title>Test</title>
</head>
<body>
<?php echo $form->render(new Zend_View());?>
</body>
</html>

You can run the above example standalone in your browser. It shows you the behaviour of Zend_Validate_Identical and how to combine it efficent within Zend_Form.

For us the important line is:

$form->addElement('password', 'password1');
$form->addElement('password', 'password2', array(
    'validators' => array(
        array('Identical', false, array('token' => 'password1'))
    )
));

As you see we added the Identical validator to the second element by using the first elements name as token.
This way the value of the first element is compared with the value of the second element.

Simple as is :-)

This is handy when you want to validate two user inputs. For example when your user has to enter his email adress two times to be sure he did not mistype it, or he has to enter the same password two times.

Note that these two described features are available within trunk and as with ZF 1.10.5 and NOT BELOW.

I hope you find this two features useful. More to come soon…

Greetings
Thomas Weidner
I18N Team Leader, Zend Framework

Zend Framework Advisory Board Member
Zend Certified Engineer for Zend Framework

Back to top