ENHANCEMENT Added i18nEntityProvider interface (see comments in #1625) incl. unit tests

MINOR documentation for i18nTextCollector

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@65022 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2008-11-01 13:26:08 +00:00
parent b81ecaaa3f
commit 4ecb895b0a
4 changed files with 136 additions and 14 deletions

View File

@ -0,0 +1,52 @@
<?php
/**
* Dynamically provide translatable entites for the {@link i18n} logic.
* This is particularly handy for natural language strings in static variables
* of a class definition, as the _t() method can only be used in a runtime/instance
* context. The provideI18nEntities() method enables you to define your own entities
* with your custom naming, mostly involving either the variable name or the array
* key. With this in place, you can use a getter method to trigger translation
* of your values.
* For any statics containing natural language, never use the static directly -
* always wrap it in a getter.
*
* @package sapphire
* @subpackage i18n
*/
interface i18nEntityProvider {
/**
* Example usage:
* <code>
* class MyTestClass implements i18nEntityProvider {
* function provideI18nEntities() {
* $entities = array();
* foreach($this->stat('my_static_array) as $key => $value) {
* $entities["MyTestClass.my_static_array_{$key}"] = array(
* $value,
* PR_MEDIUM,
* 'My context description'
* );
* }
* return $entities;
* }
*
* static function my_static_array() {
* $t_my_static_array = array();
* foreach(self::$my_static_array as $k => $v) {
* $t_my_static_array[$k] = _t("MyTestClass.my_static_array_{$key}", $v);
* }
* return $t_my_static_array;
* }
* }
* </code>
*
* Example usage in {@link DataObject->provideI18nEntities()}.
*
* @return array All entites in an associative array, with
* entity name as the key, and a numerical array of pseudo-arguments
* for _t() as a value.
*/
function provideI18nEntities();
}
?>

View File

@ -1,9 +1,29 @@
<?php
/**
* SilverStripe-variant of the "gettext" tool:
* Parses the string content of all PHP-files and SilverStripe templates
* for ocurrences of the _t() translation method. Also uses the {@link i18nEntityProvider}
* interface to get dynamically defined entities by executing the
* {@link provideI18nEntities()} method on all implementors of this interface.
*
* Collects all found entities (and their natural language text for the default locale)
* into language-files for each module in an array notation. Creates or overwrites these files,
* e.g. sapphire/lang/en_US.php.
*
* The collector needs to be run whenever you make new translatable
* entities available. Please don't alter the arrays in language tables manually.
*
* Usage through URL: http://localhost/dev/tasks/i18nTextCollector
* Usage through URL (module-specific): http://localhost/dev/tasks/i18nTextCollector/?module=mymodule
* Usage on CLI: sake dev/tasks/i18nTextCollector
* Usage on CLI (module-specific): sake dev/tasks/i18nTextCollector module=mymodule
*
* @author Bernat Foj Capell <bernat@silverstripe.com>
* @author Ingo Schommer <FIRSTNAME@silverstripe.com>
* @package sapphire
* @subpackage misc
* @subpackage i18n
* @uses i18nEntityProvider
* @uses i18n
*/
class i18nTextCollector extends Object {
@ -321,7 +341,9 @@ class i18nTextCollector extends Object {
$classes = ClassInfo::classes_for_file($filePath);
if($classes) foreach($classes as $class) {
if(class_exists($class) && method_exists($class, 'provideI18nEntities')) {
// Not all classes can be instanciated without mandatory arguments,
// so entity collection doesn't work for all SilverStripe classes currently
if(class_exists($class) && in_array('i18nEntityProvider', class_implements(new $class))) {
$obj = singleton($class);
$entitiesArr = array_merge($entitiesArr,(array)$obj->provideI18nEntities());
}

View File

@ -53,7 +53,7 @@
* @package sapphire
* @subpackage model
*/
class DataObject extends ViewableData implements DataObjectInterface {
class DataObject extends ViewableData implements DataObjectInterface,i18nEntityProvider {
/**
* Data stored in this objects database record. An array indexed
* by fieldname.

View File

@ -14,37 +14,38 @@ class i18nTest extends SapphireTest {
global $lang;
$oldLocale = i18n::get_locale();
i18n::set_locale('de_DE');
$obj = new i18nTest_Object();
$obj = new i18nTest_DataObject();
$lang['en_US']['i18nTest_Object']['db_MyProperty'] = 'MyProperty';
$lang['de_DE']['i18nTest_Object']['db_MyProperty'] = 'Mein Attribut';
$lang['en_US']['i18nTest_DataObject']['db_MyProperty'] = 'MyProperty';
$lang['de_DE']['i18nTest_DataObject']['db_MyProperty'] = 'Mein Attribut';
$this->assertEquals(
$obj->fieldLabel('MyProperty'),
'Mein Attribut'
);
$lang['en_US']['i18nTest_Object']['has_one_HasOneRelation'] = 'HasOneRelation';
$lang['de_DE']['i18nTest_Object']['has_one_HasOneRelation'] = 'Eins zu eins';
$lang['en_US']['i18nTest_DataObject']['has_one_HasOneRelation'] = 'HasOneRelation';
$lang['de_DE']['i18nTest_DataObject']['has_one_HasOneRelation'] = 'Eins zu eins';
$this->assertEquals(
$obj->fieldLabel('HasOneRelation'),
'Eins zu eins'
);
$lang['en_US']['i18nTest_Object']['has_many_HasManyRelation'] = 'HasManyRelation';
$lang['de_DE']['i18nTest_Object']['has_many_HasManyRelation'] = 'Viel zu eins';
$lang['en_US']['i18nTest_DataObject']['has_many_HasManyRelation'] = 'HasManyRelation';
$lang['de_DE']['i18nTest_DataObject']['has_many_HasManyRelation'] = 'Viel zu eins';
$this->assertEquals(
$obj->fieldLabel('HasManyRelation'),
'Viel zu eins'
);
$lang['en_US']['i18nTest_Object']['many_many_ManyManyRelation'] = 'ManyManyRelation';
$lang['de_DE']['i18nTest_Object']['many_many_ManyManyRelation'] = 'Viel zu viel';
$lang['en_US']['i18nTest_DataObject']['many_many_ManyManyRelation'] = 'ManyManyRelation';
$lang['de_DE']['i18nTest_DataObject']['many_many_ManyManyRelation'] = 'Viel zu viel';
$this->assertEquals(
$obj->fieldLabel('ManyManyRelation'),
'Viel zu viel'
);
$lang['en_US']['i18nTest_Object']['db_MyUntranslatedProperty'] = 'MyUntranslatedProperty';
$lang['en_US']['i18nTest_DataObject']['db_MyUntranslatedProperty'] = 'MyUntranslatedProperty';
$this->assertEquals(
$obj->fieldLabel('MyUntranslatedProperty'),
'My Untranslated Property'
@ -53,9 +54,40 @@ class i18nTest extends SapphireTest {
i18n::set_locale($oldLocale);
}
function testProvideI18nEntities() {
global $lang;
$oldLocale = i18n::get_locale();
$lang['en_US']['i18nTest_Object']['my_translatable_property'] = 'Untranslated';
$lang['de_DE']['i18nTest_Object']['my_translatable_property'] = 'Übersetzt';
i18n::set_locale('en_US');
$this->assertEquals(
i18nTest_Object::$my_translatable_property,
'Untranslated'
);
$this->assertEquals(
i18nTest_Object::my_translatable_property(),
'Untranslated'
);
i18n::set_locale('en_US');
$this->assertEquals(
i18nTest_Object::my_translatable_property(),
'Untranslated',
'Getter returns original static value when called in default locale'
);
i18n::set_locale('de_DE');
$this->assertEquals(
i18nTest_Object::my_translatable_property(),
'Übersetzt',
'Getter returns translated value when called in another locale'
);
}
}
class i18nTest_Object extends DataObject implements TestOnly {
class i18nTest_DataObject extends DataObject implements TestOnly {
static $db = array(
'MyProperty' => 'Varchar',
@ -75,4 +107,20 @@ class i18nTest_Object extends DataObject implements TestOnly {
);
}
class i18nTest_Object extends Object implements TestOnly, i18nEntityProvider {
static $my_translatable_property = "Untranslated";
static function my_translatable_property() {
return _t("i18nTest_Object.my_translatable_property", self::$my_translatable_property);
}
function provideI18nEntities() {
return array(
"i18nTest_Object.my_translatable_property" => array(
self::$my_translatable_property
)
);
}
}
?>