adding console command to generate javascript translation files based on existing php translation files
read server side translations from json files
This commit is contained in:
parent
d71cd680dd
commit
2f19de11e4
|
@ -0,0 +1,120 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> and
|
||||||
|
* Copyright (c) 2014 Stephen Colebrook <scolebrook@mac.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or
|
||||||
|
* later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OC\Core\Command\L10n;
|
||||||
|
|
||||||
|
use DirectoryIterator;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
class CreateJs extends Command {
|
||||||
|
|
||||||
|
protected function configure() {
|
||||||
|
$this
|
||||||
|
->setName('l10n:createjs')
|
||||||
|
->setDescription('Create javascript translation files for a given app')
|
||||||
|
->addArgument(
|
||||||
|
'app',
|
||||||
|
InputOption::VALUE_REQUIRED,
|
||||||
|
'name of the app'
|
||||||
|
)
|
||||||
|
->addArgument(
|
||||||
|
'lang',
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'name of the language'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output) {
|
||||||
|
$app = $input->getArgument('app');
|
||||||
|
$lang = $input->getArgument('lang');
|
||||||
|
|
||||||
|
$path = \OC_App::getAppPath($app);
|
||||||
|
if ($path === false) {
|
||||||
|
$output->writeln("The app <$app> is unknown.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$languages = $lang;
|
||||||
|
if (empty($lang)) {
|
||||||
|
$languages= $this->getAllLanguages($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($languages as $lang) {
|
||||||
|
$this->writeFiles($app, $path, $lang, $output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getAllLanguages($path) {
|
||||||
|
$result = array();
|
||||||
|
foreach (new DirectoryIterator("$path/l10n") as $fileInfo) {
|
||||||
|
if($fileInfo->isDot()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if($fileInfo->isDir()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if($fileInfo->getExtension() !== 'php') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$result[]= substr($fileInfo->getBasename(), 0, -4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function writeFiles($app, $path, $lang, OutputInterface $output) {
|
||||||
|
list($translations, $plurals) = $this->loadTranslations($path, $lang);
|
||||||
|
$this->writeJsFile($app, $path, $lang, $output, $translations, $plurals);
|
||||||
|
$this->writeJsonFile($path, $lang, $output, $translations, $plurals);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function writeJsFile($app, $path, $lang, OutputInterface $output, $translations, $plurals) {
|
||||||
|
$jsFile = "$path/l10n/$lang.js";
|
||||||
|
if (file_exists($jsFile)) {
|
||||||
|
$output->writeln("File already exists: $jsFile");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$content = "OC.L10N.register(\n \"$app\",\n {\n ";
|
||||||
|
$jsTrans = array();
|
||||||
|
foreach ($translations as $id => $val) {
|
||||||
|
if (is_array($val)) {
|
||||||
|
$val = '[ ' . join(',', $val) . ']';
|
||||||
|
}
|
||||||
|
$jsTrans[] = "\"$id\" : \"$val\"";
|
||||||
|
}
|
||||||
|
$content .= join(",\n ", $jsTrans);
|
||||||
|
$content .= "\n},\n\"$plurals\");\n";
|
||||||
|
|
||||||
|
file_put_contents($jsFile, $content);
|
||||||
|
$output->writeln("Javascript translation file generated: $jsFile");
|
||||||
|
}
|
||||||
|
|
||||||
|
private function writeJsonFile($path, $lang, OutputInterface $output, $translations, $plurals) {
|
||||||
|
$jsFile = "$path/l10n/$lang.json";
|
||||||
|
if (file_exists($jsFile)) {
|
||||||
|
$output->writeln("File already exists: $jsFile");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$content = array('translations' => $translations, 'pluralForm' => $plurals);
|
||||||
|
file_put_contents($jsFile, json_encode($content));
|
||||||
|
$output->writeln("Json translation file generated: $jsFile");
|
||||||
|
}
|
||||||
|
|
||||||
|
private function loadTranslations($path, $lang) {
|
||||||
|
$phpFile = "$path/l10n/$lang.php";
|
||||||
|
$TRANSLATIONS = array();
|
||||||
|
$PLURAL_FORMS = '';
|
||||||
|
require $phpFile;
|
||||||
|
|
||||||
|
return array($TRANSLATIONS, $PLURAL_FORMS);
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,4 +22,5 @@ $application->add(new OC\Core\Command\Maintenance\Repair($repair, OC_Config::get
|
||||||
$application->add(new OC\Core\Command\User\Report());
|
$application->add(new OC\Core\Command\User\Report());
|
||||||
$application->add(new OC\Core\Command\User\ResetPassword(\OC::$server->getUserManager()));
|
$application->add(new OC\Core\Command\User\ResetPassword(\OC::$server->getUserManager()));
|
||||||
$application->add(new OC\Core\Command\User\LastSeen());
|
$application->add(new OC\Core\Command\User\LastSeen());
|
||||||
|
$application->add(new OC\Core\Command\L10n\CreateJs());
|
||||||
|
|
||||||
|
|
19
l10n/l10n.pl
19
l10n/l10n.pl
|
@ -120,7 +120,7 @@ if( $task eq 'read' ){
|
||||||
my $language = ( $file =~ /\.js$/ ? 'Python' : 'PHP');
|
my $language = ( $file =~ /\.js$/ ? 'Python' : 'PHP');
|
||||||
my $joinexisting = ( -e $output ? '--join-existing' : '');
|
my $joinexisting = ( -e $output ? '--join-existing' : '');
|
||||||
print " Reading $file\n";
|
print " Reading $file\n";
|
||||||
`xgettext --output="$output" $joinexisting $keywords --language=$language "$file" --add-comments=TRANSLATORS --from-code=UTF-8 --package-version="6.0.0" --package-name="ownCloud Core" --msgid-bugs-address="translations\@owncloud.org"`;
|
`xgettext --output="$output" $joinexisting $keywords --language=$language "$file" --add-comments=TRANSLATORS --from-code=UTF-8 --package-version="8.0.0" --package-name="ownCloud Core" --msgid-bugs-address="translations\@owncloud.org"`;
|
||||||
}
|
}
|
||||||
chdir( $whereami );
|
chdir( $whereami );
|
||||||
}
|
}
|
||||||
|
@ -176,19 +176,24 @@ elsif( $task eq 'write' ){
|
||||||
s/\$/\\\$/g;
|
s/\$/\\\$/g;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Write PHP file
|
# delete old php file
|
||||||
open( OUT, ">$language.php" );
|
unlink "$language.php";
|
||||||
print OUT "<?php\n\$TRANSLATIONS = array(\n";
|
|
||||||
print OUT join( ",\n", @strings );
|
|
||||||
print OUT "\n);\n\$PLURAL_FORMS = \"$plurals\";\n";
|
|
||||||
close( OUT );
|
|
||||||
|
|
||||||
|
# Write js file
|
||||||
open( OUT, ">$language.js" );
|
open( OUT, ">$language.js" );
|
||||||
print OUT "OC.L10N.register(\n \"$app\",\n {\n ";
|
print OUT "OC.L10N.register(\n \"$app\",\n {\n ";
|
||||||
print OUT join( ",\n ", @js_strings );
|
print OUT join( ",\n ", @js_strings );
|
||||||
print OUT "\n},\n\"$plurals\");\n";
|
print OUT "\n},\n\"$plurals\");\n";
|
||||||
close( OUT );
|
close( OUT );
|
||||||
|
|
||||||
|
# Write json file
|
||||||
|
open( OUT, ">$language.json" );
|
||||||
|
print OUT "{ \"translations\": ";
|
||||||
|
print OUT "{\n ";
|
||||||
|
print OUT join( ",\n ", @js_strings );
|
||||||
|
print OUT "\n},\"pluralForm\" :\"$plurals\"\n}";
|
||||||
|
close( OUT );
|
||||||
|
|
||||||
}
|
}
|
||||||
chdir( $whereami );
|
chdir( $whereami );
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,12 +54,12 @@ class OC_L10N implements \OCP\IL10N {
|
||||||
/**
|
/**
|
||||||
* Plural forms (string)
|
* Plural forms (string)
|
||||||
*/
|
*/
|
||||||
private $plural_form_string = 'nplurals=2; plural=(n != 1);';
|
private $pluralFormString = 'nplurals=2; plural=(n != 1);';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plural forms (function)
|
* Plural forms (function)
|
||||||
*/
|
*/
|
||||||
private $plural_form_function = null;
|
private $pluralFormFunction = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get an L10N instance
|
* get an L10N instance
|
||||||
|
@ -90,16 +90,26 @@ class OC_L10N implements \OCP\IL10N {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $transFile
|
* @param string $transFile
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function load($transFile) {
|
public function load($transFile, $mergeTranslations = false) {
|
||||||
$this->app = true;
|
$this->app = true;
|
||||||
include $transFile;
|
|
||||||
if(isset($TRANSLATIONS) && is_array($TRANSLATIONS)) {
|
$json = json_decode(file_get_contents($transFile), true);
|
||||||
$this->translations = $TRANSLATIONS;
|
if (!is_array($json)) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
if(isset($PLURAL_FORMS)) {
|
|
||||||
$this->plural_form_string = $PLURAL_FORMS;
|
$this->pluralFormString = $json['pluralForm'];
|
||||||
|
$translations = $json['translations'];
|
||||||
|
|
||||||
|
if ($mergeTranslations) {
|
||||||
|
$this->translations = array_merge($this->translations, $translations);
|
||||||
|
} else {
|
||||||
|
$this->translations = $translations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function init() {
|
protected function init() {
|
||||||
|
@ -118,36 +128,28 @@ class OC_L10N implements \OCP\IL10N {
|
||||||
if(array_key_exists($app.'::'.$lang, self::$cache)) {
|
if(array_key_exists($app.'::'.$lang, self::$cache)) {
|
||||||
$this->translations = self::$cache[$app.'::'.$lang]['t'];
|
$this->translations = self::$cache[$app.'::'.$lang]['t'];
|
||||||
} else{
|
} else{
|
||||||
$i18ndir = self::findI18nDir($app);
|
$i18nDir = self::findI18nDir($app);
|
||||||
|
$transFile = strip_tags($i18nDir).strip_tags($lang).'.json';
|
||||||
// Texts are in $i18ndir
|
// Texts are in $i18ndir
|
||||||
// (Just no need to define date/time format etc. twice)
|
// (Just no need to define date/time format etc. twice)
|
||||||
if((OC_Helper::isSubDirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/core/l10n/')
|
if((OC_Helper::isSubDirectory($transFile, OC::$SERVERROOT.'/core/l10n/')
|
||||||
|| OC_Helper::isSubDirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/lib/l10n/')
|
|| OC_Helper::isSubDirectory($transFile, OC::$SERVERROOT.'/lib/l10n/')
|
||||||
|| OC_Helper::isSubDirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/settings')
|
|| OC_Helper::isSubDirectory($transFile, OC::$SERVERROOT.'/settings')
|
||||||
|| OC_Helper::isSubDirectory($i18ndir.$lang.'.php', OC_App::getAppPath($app).'/l10n/')
|
|| OC_Helper::isSubDirectory($transFile, OC_App::getAppPath($app).'/l10n/')
|
||||||
)
|
)
|
||||||
&& file_exists($i18ndir.$lang.'.php')) {
|
&& file_exists($transFile)) {
|
||||||
// Include the file, save the data from $CONFIG
|
// load the translations file
|
||||||
$transFile = strip_tags($i18ndir).strip_tags($lang).'.php';
|
if($this->load($transFile)) {
|
||||||
include $transFile;
|
|
||||||
if(isset($TRANSLATIONS) && is_array($TRANSLATIONS)) {
|
|
||||||
$this->translations = $TRANSLATIONS;
|
|
||||||
//merge with translations from theme
|
//merge with translations from theme
|
||||||
$theme = OC_Config::getValue( "theme" );
|
$theme = OC_Config::getValue( "theme" );
|
||||||
if (!is_null($theme)) {
|
if (!is_null($theme)) {
|
||||||
$transFile = OC::$SERVERROOT.'/themes/'.$theme.substr($transFile, strlen(OC::$SERVERROOT));
|
$transFile = OC::$SERVERROOT.'/themes/'.$theme.substr($transFile, strlen(OC::$SERVERROOT));
|
||||||
if (file_exists($transFile)) {
|
if (file_exists($transFile)) {
|
||||||
include $transFile;
|
$this->load($transFile, true);
|
||||||
if (isset($TRANSLATIONS) && is_array($TRANSLATIONS)) {
|
|
||||||
$this->translations = array_merge($this->translations, $TRANSLATIONS);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(isset($PLURAL_FORMS)) {
|
|
||||||
$this->plural_form_string = $PLURAL_FORMS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self::$cache[$app.'::'.$lang]['t'] = $this->translations;
|
self::$cache[$app.'::'.$lang]['t'] = $this->translations;
|
||||||
}
|
}
|
||||||
|
@ -273,10 +275,10 @@ class OC_L10N implements \OCP\IL10N {
|
||||||
*/
|
*/
|
||||||
public function getPluralFormFunction() {
|
public function getPluralFormFunction() {
|
||||||
$this->init();
|
$this->init();
|
||||||
if(is_null($this->plural_form_function)) {
|
if(is_null($this->pluralFormFunction)) {
|
||||||
$this->plural_form_function = $this->createPluralFormFunction($this->plural_form_string);
|
$this->pluralFormFunction = $this->createPluralFormFunction($this->pluralFormString);
|
||||||
}
|
}
|
||||||
return $this->plural_form_function;
|
return $this->pluralFormFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -479,8 +481,8 @@ class OC_L10N implements \OCP\IL10N {
|
||||||
if(is_dir($dir)) {
|
if(is_dir($dir)) {
|
||||||
$files=scandir($dir);
|
$files=scandir($dir);
|
||||||
foreach($files as $file) {
|
foreach($files as $file) {
|
||||||
if(substr($file, -4, 4) === '.php' && substr($file, 0, 4) !== 'l10n') {
|
if(substr($file, -5, 5) === '.json' && substr($file, 0, 4) !== 'l10n') {
|
||||||
$i = substr($file, 0, -4);
|
$i = substr($file, 0, -5);
|
||||||
$available[] = $i;
|
$available[] = $i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"translations" : {
|
||||||
|
"_%n window_::_%n windows_" : ["%n okno", "%n okna", "%n oken"]
|
||||||
|
},
|
||||||
|
"pluralForm" : "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
|
||||||
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
<?php
|
|
||||||
$TRANSLATIONS = array(
|
|
||||||
"_%n window_::_%n windows_" => array("%n okno", "%n okna", "%n oken")
|
|
||||||
);
|
|
||||||
$PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;";
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"translations" : {
|
||||||
|
"_%n file_::_%n files_": ["%n Datei", "%n Dateien"]
|
||||||
|
},
|
||||||
|
"pluralForm" : "nplurals=2; plural=(n != 1);"
|
||||||
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
<?php
|
|
||||||
$TRANSLATIONS = array(
|
|
||||||
"_%n file_::_%n files_" => array("%n Datei", "%n Dateien")
|
|
||||||
);
|
|
||||||
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"translations" : {
|
||||||
|
"_%n file_::_%n files_" : ["%n файл", "%n файла", "%n файлов"]
|
||||||
|
},
|
||||||
|
"pluralForm" : "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
|
||||||
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
<?php
|
|
||||||
$TRANSLATIONS = array(
|
|
||||||
"_%n file_::_%n files_" => array("%n файл", "%n файла", "%n файлов")
|
|
||||||
);
|
|
||||||
$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";
|
|
|
@ -10,7 +10,7 @@ class Test_L10n extends PHPUnit_Framework_TestCase {
|
||||||
|
|
||||||
public function testGermanPluralTranslations() {
|
public function testGermanPluralTranslations() {
|
||||||
$l = new OC_L10N('test');
|
$l = new OC_L10N('test');
|
||||||
$transFile = OC::$SERVERROOT.'/tests/data/l10n/de.php';
|
$transFile = OC::$SERVERROOT.'/tests/data/l10n/de.json';
|
||||||
|
|
||||||
$l->load($transFile);
|
$l->load($transFile);
|
||||||
$this->assertEquals('1 Datei', (string)$l->n('%n file', '%n files', 1));
|
$this->assertEquals('1 Datei', (string)$l->n('%n file', '%n files', 1));
|
||||||
|
@ -19,7 +19,7 @@ class Test_L10n extends PHPUnit_Framework_TestCase {
|
||||||
|
|
||||||
public function testRussianPluralTranslations() {
|
public function testRussianPluralTranslations() {
|
||||||
$l = new OC_L10N('test');
|
$l = new OC_L10N('test');
|
||||||
$transFile = OC::$SERVERROOT.'/tests/data/l10n/ru.php';
|
$transFile = OC::$SERVERROOT.'/tests/data/l10n/ru.json';
|
||||||
|
|
||||||
$l->load($transFile);
|
$l->load($transFile);
|
||||||
$this->assertEquals('1 файл', (string)$l->n('%n file', '%n files', 1));
|
$this->assertEquals('1 файл', (string)$l->n('%n file', '%n files', 1));
|
||||||
|
@ -44,7 +44,7 @@ class Test_L10n extends PHPUnit_Framework_TestCase {
|
||||||
|
|
||||||
public function testCzechPluralTranslations() {
|
public function testCzechPluralTranslations() {
|
||||||
$l = new OC_L10N('test');
|
$l = new OC_L10N('test');
|
||||||
$transFile = OC::$SERVERROOT.'/tests/data/l10n/cs.php';
|
$transFile = OC::$SERVERROOT.'/tests/data/l10n/cs.json';
|
||||||
|
|
||||||
$l->load($transFile);
|
$l->load($transFile);
|
||||||
$this->assertEquals('1 okno', (string)$l->n('%n window', '%n windows', 1));
|
$this->assertEquals('1 okno', (string)$l->n('%n window', '%n windows', 1));
|
||||||
|
|
Loading…
Reference in New Issue