ENHANCEMENT New i18nTextCollector_Writer_RailsYaml

This commit is contained in:
Ingo Schommer 2012-04-14 01:01:59 +02:00
parent fca2c205b7
commit cbcee57496
3 changed files with 110 additions and 3 deletions

View File

@ -220,13 +220,35 @@ If you want to run the text collector for just one module you can use the 'modul
**Note**: You'll need to install PHPUnit to run the text collector (see [testing-guide](/topics/testing)). **Note**: You'll need to install PHPUnit to run the text collector (see [testing-guide](/topics/testing)).
</div> </div>
## Language definitions ## Language definitions (3.x)
Each module can have one language table per locale, stored by convention in the `lang/` subfolder. Each module can have one language table per locale, stored by convention in the `lang/` subfolder.
The translation is powered by `[Zend_Translate](http://framework.zend.com/manual/en/zend.translate.html)`, The translation is powered by `[Zend_Translate](http://framework.zend.com/manual/en/zend.translate.html)`,
which supports different translation adapters, dealing with different storage formats. which supports different translation adapters, dealing with different storage formats.
In SilverStripe 2.x, there tables are just PHP files with array notations, By default, SilverStripe 3.x uses a YAML format (through the [Zend_Translate_RailsYAML adapter](https://github.com/chillu/zend_translate_railsyaml)).
Example: sapphire/lang/en.yml (extract)
:::yml
en:
ImageUploader:
Attach: 'Attach %s'
FileIFrameField:
NOTEADDFILES: 'You can add files once you have saved for the first time.'
Translation table: sapphire/lang/de.yml (extract)
:::yml
de:
ImageUploader:
ATTACH: '%s anhängen'
FileIframeField:
NOTEADDFILES: 'Sie können Dateien hinzufügen sobald Sie das erste mal gespeichert haben'
## Language definitions (2.x)
In SilverStripe 2.x, the tables are just PHP files with array notations,
stored based on their locale name (e.g. "en_US.php"). stored based on their locale name (e.g. "en_US.php").
Example: framework/lang/en_US.php (extract) Example: framework/lang/en_US.php (extract)
@ -247,6 +269,19 @@ Translation table: framework/lang/de_DE.php (extract)
$lang['de_DE']['ImageUploader']['ATTACH'] = '%s anhängen'; $lang['de_DE']['ImageUploader']['ATTACH'] = '%s anhängen';
$lang['de_DE']['FileIframeField']['NOTEADDFILES'] = 'Sie können Dateien hinzufügen sobald Sie das erste mal gespeichert haben'; $lang['de_DE']['FileIframeField']['NOTEADDFILES'] = 'Sie können Dateien hinzufügen sobald Sie das erste mal gespeichert haben';
In order to enable usage of PHP language definitions in 3.x, you need to register a legacy adapter
in your `mysite/_config.php`:
:::php
i18n::register_translator(
new Zend_Translate(array(
'adapter' => 'i18nSSLegacyAdapter',
'locale' => i18n::default_locale(),
'disableNotices' => true,
)),
'legacy',
9 // priority lower than standard translator
);
## Javascript Usage ## Javascript Usage

View File

@ -61,7 +61,7 @@ class i18nTextCollector extends Object {
} }
public function getWriter() { public function getWriter() {
if(!$this->writer) $this->writer = new i18nTextCollector_Writer_Php(); if(!$this->writer) $this->writer = new i18nTextCollector_Writer_RailsYaml();
return $this->writer; return $this->writer;
} }
@ -452,3 +452,55 @@ class i18nTextCollector_Writer_Php implements i18nTextCollector_Writer {
return $php; return $php;
} }
} }
/**
* Writes files compatible with {@link i18nRailsYamlAdapter}.
*/
class i18nTextCollector_Writer_RailsYaml implements i18nTextCollector_Writer {
public function write($entities, $locale, $path) {
$content = '';
// Create folder for lang files
$langFolder = $path . '/lang';
if(!file_exists($langFolder)) {
Filesystem::makeFolder($langFolder, Filesystem::$folder_create_mask);
touch($langFolder . '/_manifest_exclude');
}
// Open the English file and write the Master String Table
$langFile = $langFolder . '/' . $locale . '.yml';
if($fh = fopen($langFile, "w")) {
fwrite($fh, $this->getYaml($entities,$locale));
fclose($fh);
} else {
throw new LogicException("Cannot write language file! Please check permissions of $langFile");
}
return true;
}
public function getYaml($entities, $locale) {
if(!class_exists('sfYamlDumper', false)) require_once 'thirdparty/symfony-yaml/lib/sfYamlDumper.php';
// Unflatten array
$entitiesNested = array();
foreach($entities as $entity => $spec) {
// Legacy support: Don't count *.ss as namespace
$entity = preg_replace('/\.ss\./', '___ss.', $entity);
$parts = explode('.', $entity);
$currLevel = &$entitiesNested;
while($part = array_shift($parts)) {
$part = str_replace('___ss', '.ss', $part);
if(!isset($currLevel[$part])) $currLevel[$part] = array();
$currLevel = &$currLevel[$part];
}
$currLevel = $spec[0];
}
// Write YAML
$yamlHandler = new sfYaml();
// TODO Dumper can't handle YAML comments, so the context information is currently discarded
return $yamlHandler->dump(array($locale => $entitiesNested), 99);
}
}

View File

@ -329,6 +329,26 @@ PHP;
$php $php
); );
} }
/**
* @todo Should be in a separate test suite, but don't want to duplicate setup logic
*/
function testYamlWriter() {
$writer = new i18nTextCollector_Writer_RailsYaml();
$entities = array(
'Level1.Level2.EntityName' => array('Text', 'Context'),
'Level1.OtherEntityName' => array('Other Text', 'Other Context'),
);
$yaml = <<<YAML
de:
Level1:
Level2:
EntityName: Text
OtherEntityName: 'Other Text'
YAML;
$this->assertEquals($yaml, $writer->getYaml($entities, 'de'));
}
function testCollectFromIncludedTemplates() { function testCollectFromIncludedTemplates() {
$c = new i18nTextCollector(); $c = new i18nTextCollector();