Commit bbcee326 by Carsten Brandt

adjusted I18N to be consistent with intl message formatting

parent 2eb5abbf
......@@ -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
......
......@@ -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);
}
/**
......
<?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.',
);
\ No newline at end of file
<?php
/**
*
*/
return array(
'The dog runs fast.' => 'Der Hund rennt schell.',
);
\ No newline at end of file
<?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'));
}
}
\ No newline at end of file
......@@ -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);
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment