Browse Source

adjusted I18N to be consistent with intl message formatting

tags/2.0.0-beta
Carsten Brandt 11 years ago
parent
commit
bbcee326be
  1. 5
      docs/guide/i18n.md
  2. 29
      framework/yii/i18n/I18N.php
  3. 9
      tests/unit/data/i18n/messages/de_DE/test.php
  4. 7
      tests/unit/data/i18n/messages/en_US/test.php
  5. 65
      tests/unit/framework/i18n/I18NTest.php
  6. 19
      tests/unit/framework/i18n/MessageFormatterTest.php

5
docs/guide/i18n.md

@ -53,6 +53,9 @@ TBD: https://github.com/yiisoft/yii2/issues/930
### Named placeholders
You can add parameters to a translation message that will be substituted with the corresponding value after translation.
The format for this is to use curly brackets around the parameter name as you can see in the following example:
```php
$username = 'Alexander';
echo \Yii::t('app', 'Hello, {username}!', array(
@ -60,6 +63,8 @@ echo \Yii::t('app', 'Hello, {username}!', array(
));
```
Note that the parameter assignment is without the brackets.
### Positional placeholders
```php

29
framework/yii/i18n/I18N.php

@ -73,24 +73,31 @@ class I18N extends Component
public function translate($category, $message, $params, $language)
{
$message = $this->getMessageSource($category)->translate($category, $message, $language);
$params = (array)$params;
if (empty($params)) {
return $message;
}
$params = (array)$params;
if (class_exists('MessageFormatter', false) && preg_match('~{\s*[\d\w]+\s*,~u', $message)) {
$formatter = new MessageFormatter($language, $message);
if ($formatter === null) {
\Yii::$app->getLog()->log("$language message from category $category failed. Message is: $message.", Logger::LEVEL_WARNING, 'application');
}
$result = $formatter->format($params);
if ($result === false) {
$errorMessage = $formatter->getErrorMessage();
\Yii::$app->getLog()->log("$language message from category $category failed with error: $errorMessage. Message is: $message.", Logger::LEVEL_WARNING, 'application');
}
else {
return $result;
\Yii::$app->getLog()->log("$language message from category $category is invalid. Message is: $message.", Logger::LEVEL_WARNING, 'application');
} else {
$result = $formatter->format($params);
if ($result === false) {
$errorMessage = $formatter->getErrorMessage();
\Yii::$app->getLog()->log("$language message from category $category failed with error: $errorMessage. Message is: $message.", Logger::LEVEL_WARNING, 'application');
} else {
return $result;
}
}
}
return empty($params) ? $message : strtr($message, $params);
$p = array();
foreach($params as $name => $value) {
$p['{' . $name . '}'] = $value;
}
return strtr($message, $p);
}
/**

9
tests/unit/data/i18n/messages/de_DE/test.php

@ -0,0 +1,9 @@
<?php
/**
*
*/
return array(
'The dog runs fast.' => 'Der Hund rennt schnell.',
'His speed is about {n} km/h.' => 'Seine Geschwindigkeit beträgt {n} km/h.',
'His name is {name} and his speed is about {n, number} km/h.' => 'Er heißt {name} und ist {n, number} km/h schnell.',
);

7
tests/unit/data/i18n/messages/en_US/test.php

@ -0,0 +1,7 @@
<?php
/**
*
*/
return array(
'The dog runs fast.' => 'Der Hund rennt schell.',
);

65
tests/unit/framework/i18n/I18NTest.php

@ -0,0 +1,65 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yiiunit\framework\i18n;
use yii\i18n\I18N;
use yii\i18n\MessageFormatter;
use yii\i18n\PhpMessageSource;
use yiiunit\TestCase;
/**
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
* @group i18n
*/
class I18NTest extends TestCase
{
/**
* @var I18N
*/
public $i18n;
protected function setUp()
{
parent::setUp();
$this->mockApplication();
$this->i18n = new I18N(array(
'translations' => array(
'test' => new PhpMessageSource(array(
'basePath' => '@yiiunit/data/i18n/messages',
))
)
));
}
public function testTranslate()
{
$msg = 'The dog runs fast.';
$this->assertEquals('The dog runs fast.', $this->i18n->translate('test', $msg, array(), 'en_US'));
$this->assertEquals('Der Hund rennt schnell.', $this->i18n->translate('test', $msg, array(), 'de_DE'));
}
public function testTranslateParams()
{
$msg = 'His speed is about {n} km/h.';
$params = array(
'n' => 42,
);
$this->assertEquals('His speed is about 42 km/h.', $this->i18n->translate('test', $msg, $params, 'en_US'));
$this->assertEquals('Seine Geschwindigkeit beträgt 42 km/h.', $this->i18n->translate('test', $msg, $params, 'de_DE'));
$msg = 'His name is {name} and his speed is about {n, number} km/h.';
$params = array(
'n' => 42,
'name' => 'DA VINCI', // http://petrix.com/dognames/d.html
);
$this->assertEquals('His name is DA VINCI and his speed is about 42 km/h.', $this->i18n->translate('test', $msg, $params, 'en_US'));
$this->assertEquals('Er heißt DA VINCI und ist 42 km/h schnell.', $this->i18n->translate('test', $msg, $params, 'de_DE'));
}
}

19
tests/unit/framework/i18n/MessageFormatterTest.php

@ -140,4 +140,23 @@ _MSG_
$this->assertEquals($expected, $result);
}
/**
* when instantiating a MessageFormatter with invalid pattern it should be null
*/
public function testNullConstructor()
{
$this->assertNull(new MessageFormatter('en_US', ''));
}
public function testNoParams()
{
$pattern = '{'.self::SUBJECT.'} is '.self::N;
$result = MessageFormatter::formatMessage('en_US', $pattern, array());
$this->assertEquals($pattern, $result);
$formatter = new MessageFormatter('en_US', $pattern);
$result = $formatter->format(array());
$this->assertEquals($pattern, $result);
}
}
Loading…
Cancel
Save