Skip to content
Browse files

Merge pull request #1 from xini/master

Translation of all modules
  • Loading branch information...
2 parents aeb852a + 93491d1 commit dc83e89322d04b7686751e24f04f93202314e083 @unclecheese committed
View
240 code/LangEditor.php
@@ -9,21 +9,38 @@ class LangEditor extends LeftAndMain {
static $allowed_actions = array (
'TranslationForm',
'CreateTranslationForm',
- 'show'
+ 'show',
+ 'updatemodules',
+ 'updatelanguages',
+ 'updatecreateform',
+ 'doCreate',
+ 'doSave'
);
- public static function lang_dir() {
- return BASE_PATH.DIRECTORY_SEPARATOR.project().DIRECTORY_SEPARATOR."lang";
+ static $exclude_modules = array();
+
+ static $currentLocale = "";
+ static $currentModule = "";
+
+ public static function lang_dir($module) {
+ return BASE_PATH.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR."lang";
}
- public static function lang_file($lang) {
- return self::lang_dir().DIRECTORY_SEPARATOR."{$lang}.php";
+ public static function lang_file($module, $lang) {
+ return self::lang_dir($module).DIRECTORY_SEPARATOR."{$lang}.php";
}
public static function clean_namespace($str) {
return str_replace('.','___',$str);
}
+ public static function check_module_existing_lang() {
+ if (!is_file(self::lang_file(self::$currentModule, self::$currentLocale))) {
+ $langs = self::getLanguages();
+ self::$currentLocale = $langs->First()->Locale;
+ }
+ }
+
public static function get_lang_from_locale($locale) {
if($str = i18n::get_lang_from_locale($locale)) {
if(stristr($str,"_") !== false) {
@@ -35,7 +52,6 @@ public static function get_lang_from_locale($locale) {
return $locale;
}
-
public function init() {
parent::init();
Requirements::javascript(THIRDPARTY_DIR."/jquery/jquery.js");
@@ -45,14 +61,13 @@ public function init() {
Requirements::css("lang_editor/css/lang_editor.css");
}
-
- public function Languages() {
+ public function getLanguages() {
$langs = new DataObjectSet();
- if($files = glob(self::lang_dir().DIRECTORY_SEPARATOR."*.php")) {
+ if($files = glob(self::lang_dir(self::$currentModule).DIRECTORY_SEPARATOR."*.php")) {
foreach($files as $file) {
$label = basename($file,".php");
$langs->push(new ArrayData(array(
- 'Link' => $this->Link("show/$label"),
+ 'Link' => isset($this) ? $this->Link("show/$label/".str_replace(DIRECTORY_SEPARATOR, '$', self::$currentModule)): '',
'Locale' => $label,
'Name' => i18n::get_language_name(self::get_lang_from_locale($label))
)));
@@ -61,6 +76,55 @@ public function Languages() {
return $langs;
}
+ public function getModules() {
+ $modules = new DataObjectSet();
+
+ $folders = scandir(BASE_PATH);
+ $themeFolders = array();
+
+ foreach($folders as $index => $folder){
+ if($folder != 'themes') continue;
+ else {
+ $themes = scandir(BASE_PATH.DIRECTORY_SEPARATOR."themes");
+ if(count($themes)){
+ foreach($themes as $theme) {
+ if(is_dir(BASE_PATH.DIRECTORY_SEPARATOR."themes".DIRECTORY_SEPARATOR.$theme) && substr($theme,0,1) != '.' && is_dir(BASE_PATH.DIRECTORY_SEPARATOR."themes".DIRECTORY_SEPARATOR.$theme.DIRECTORY_SEPARATOR."templates")){
+ $themeFolders[] = 'themes'.DIRECTORY_SEPARATOR.$theme;
+ }
+ }
+ }
+ $themesInd = $index;
+ }
+ }
+ if(isset($themesInd)) {
+ unset($folders[$themesInd]);
+ }
+ $folders = array_merge($folders, $themeFolders);
+
+ foreach($folders as $folder) {
+ // Only search for calls in folder with a _config.php file
+ $isValidModuleFolder = (
+ !in_array($folder, self::$exclude_modules)
+ && substr($folder,0,1) != '.'
+ && is_dir(BASE_PATH.DIRECTORY_SEPARATOR."$folder")
+ && (
+ is_file(BASE_PATH.DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR."_config.php")
+ && file_exists(BASE_PATH.DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR."lang")
+ ) || (
+ substr($folder,0,7) == ('themes'.DIRECTORY_SEPARATOR)
+ && file_exists(BASE_PATH.DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR."lang")
+ )
+ );
+ if(!$isValidModuleFolder) continue;
+
+ $modules->push(new ArrayData(array(
+ 'Link' => $this->Link("show/".self::$currentLocale."/".str_replace(DIRECTORY_SEPARATOR, '$', $folder)),
+ 'Name' => $folder
+ )));
+
+ }
+ return $modules;
+ }
public function TranslationForm() {
return new Form (
@@ -73,7 +137,6 @@ public function TranslationForm() {
);
}
-
public function NamespaceDropdown() {
if($this->Namespaces) {
$map = array();
@@ -84,14 +147,23 @@ public function NamespaceDropdown() {
}
public function CreateTranslationForm() {
+ $r = Controller::curr()->getRequest();
+ if($r && $r->param('ID') && $r->param('OtherID')) {
+ self::$currentLocale = $r->param('ID');
+ self::$currentModule = str_replace('$', DIRECTORY_SEPARATOR, $r->param('OtherID'));
+ }
$from_languages = array();
$to_languages = i18n::get_common_locales();
- if($languages = $this->Languages()) {
+ if (dataObject::has_extension('SiteTree', 'Translatable')) {
+ $common_locales = $to_languages;
+ $to_languages = array();
+ foreach(Translatable::get_allowed_locales() as $locale) {
+ $to_languages[$locale] = $common_locales[$locale];
+ }
+ }
+ if($languages = $this->getLanguages()) {
foreach($languages as $l) {
$from_languages[$l->Locale] = $l->Name;
- if(isset($to_languages[$l->Locale])) {
- unset($to_languages[$l->Locale]);
- }
}
}
$f = new Form(
@@ -99,8 +171,8 @@ public function CreateTranslationForm() {
"CreateTranslationForm",
new FieldSet (
new DropdownField('LanguageFrom',_t('LangEditor.TRANSLATEFROM','From'), $from_languages, i18n::get_locale()),
- $d = new DropdownField('LanguageTo',_t('LangEditor.TRANSLATETO','To'),$to_languages)
-
+ $d = new DropdownField('LanguageTo',_t('LangEditor.TRANSLATETO','To'),$to_languages),
+ new HiddenField('Module', 'Module', self::$currentModule)
),
new FieldSet (
new FormAction('doCreate',_t('LangEditor.CREATE','Create'))
@@ -110,9 +182,9 @@ public function CreateTranslationForm() {
return $f;
}
- public function getTranslations($locale) {
+ public function getTranslations() {
$namespaces = new DataObjectSet();
- $lang_file = self::lang_file($locale);
+ $lang_file = self::lang_file(self::$currentModule, self::$currentLocale);
if(!file_exists($lang_file)) return "$lang_file does not exist!";
if(!is_readable($lang_file)) return "$lang_file is not readable!";
if(!is_writable($lang_file)) return "$lang_file is not writable!";
@@ -126,15 +198,18 @@ public function getTranslations($locale) {
$map = array();
$temp_lang = eval($code);
- if(is_array($temp_lang) && isset($temp_lang[$locale])) {
- foreach($temp_lang[$locale] as $namespace => $array_of_entities) {
+ if(is_array($temp_lang) && isset($temp_lang[self::$currentLocale])) {
+ foreach($temp_lang[self::$currentLocale] as $namespace => $array_of_entities) {
$map[self::clean_namespace($namespace)] = $namespace;
$entities = new DataObjectSet();
if(is_array($array_of_entities)) {
foreach($array_of_entities as $entity => $str) {
+ if (is_array($str)) {
+ $str = $str[0];
+ }
$entities->push(new ArrayData(array(
'Entity' => $entity,
- 'EntityField' => new TextField("t[$locale][$namespace][$entity]","",stripslashes($str)),
+ 'EntityField' => new TextField("t[".self::$currentLocale."][$namespace][$entity]","",stripslashes($str)),
'Namespace' => $namespace
)));
}
@@ -149,29 +224,70 @@ public function getTranslations($locale) {
}
$dropdown = new DropdownField('Namespace', _t('LangEditor.NAMESPACE','Namespace'), $map);
- $dropdown->setEmptyString('-- '._t('LangEditor.PLEASESELECT','Show all namespaces').' --');
+ $dropdown->setEmptyString('-- '._t('LangEditor.SHOWALLNAMESPACES','Show all namespaces').' --');
return array(
'NamespaceDropdown' => $dropdown,
'Namespaces' => $namespaces,
- 'SelectedLocale' => $locale,
- 'SelectedLanguage' => i18n::get_language_name(self::get_lang_from_locale($locale))
+ 'SelectedLocale' => self::$currentLocale,
+ 'SelectedLanguage' => i18n::get_language_name(self::get_lang_from_locale(self::$currentLocale)),
+ 'SelectedModule' => self::$currentModule
);
}
public function index() {
- return $this->getTranslations(i18n::get_locale());
+ self::$currentLocale = i18n::get_locale();
+ self::$currentModule = project();
+ self::check_module_existing_lang();
+ return $this->getTranslations();
}
public function show(SS_HTTPReqest $r) {
- if(!$l = $r->param('ID')) {
+ if(!self::$currentLocale = $r->param('ID')) {
return $this->httpError(404);
-
}
- $data = $this->getTranslations($l);
+ if(!self::$currentModule = str_replace('$', DIRECTORY_SEPARATOR, $r->param('OtherID'))) {
+ return $this->httpError(404);
+ }
+ self::check_module_existing_lang();
+ $data = $this->getTranslations();
return $this->customise($data)->renderWith('Translations');
-
}
+ public function updatemodules(SS_HTTPReqest $r) {
+ if(!self::$currentLocale = $r->param('ID')) {
+ return $this->httpError(404);
+ }
+ if(!self::$currentModule = str_replace('$', DIRECTORY_SEPARATOR, $r->param('OtherID'))) {
+ return $this->httpError(404);
+ }
+ self::check_module_existing_lang();
+ $data = $this->getModules();
+ return $this->customise($data)->renderWith('ModuleList');
+ }
+
+ public function updatelanguages(SS_HTTPReqest $r) {
+ if(!self::$currentLocale = $r->param('ID')) {
+ return $this->httpError(404);
+ }
+ if(!self::$currentModule = str_replace('$', DIRECTORY_SEPARATOR, $r->param('OtherID'))) {
+ return $this->httpError(404);
+ }
+ self::check_module_existing_lang();
+ $data = $this->getLanguages();
+ return $this->customise($data)->renderWith('LanguageList');
+ }
+
+ public function updatecreateform(SS_HTTPReqest $r) {
+ if(!self::$currentLocale = $r->param('ID')) {
+ return $this->httpError(404);
+ }
+ if(!self::$currentModule = str_replace('$', DIRECTORY_SEPARATOR, $r->param('OtherID'))) {
+ return $this->httpError(404);
+ }
+ self::check_module_existing_lang();
+ $data = $this->CreateTranslationForm();
+ return $this->customise($data)->renderWith('CreateTranslationForm');
+ }
public function doSave($data, $form) {
if(isset($data['t']) && is_array($data['t'])) {
@@ -183,7 +299,7 @@ public function doSave($data, $form) {
}
}
}
- $fh = fopen(self::lang_file(reset(array_keys($data['t']))),"w");
+ $fh = fopen(self::lang_file($data['Module'], reset(array_keys($data['t']))),"w");
fwrite($fh, $output);
fclose($fh);
return new SS_HTTPResponse(_t('LangEditor.SAVED','Saved'),200);
@@ -192,22 +308,74 @@ public function doSave($data, $form) {
public function doCreate($data, $form) {
- $to = self::lang_file($data['LanguageTo']);
- $from = self::lang_file($data['LanguageFrom']);
+
+ $message = _t('LangEditor.CREATED','Created');
+
+ self::$currentLocale = $data['LanguageTo'];
+ self::$currentModule = $data['Module'];
+
+ $to = self::lang_file($data['Module'], $data['LanguageTo']);
+ $from = self::lang_file($data['Module'], $data['LanguageFrom']);
// sanity check
- if(!file_exists($from) || file_exists($to)) {
- return new SS_HTTPResponse(_t('LangEditor.FILESNOTRIGHT','The from language does not exist, or the new language already exists!'),500);
+ if(!file_exists($from)) {
+ return new SS_HTTPResponse(_t('LangEditor.TOFILEMISSING','The from language does not exist!'),500);
}
+ // get content of source file and replace language
$new_contents = str_replace(
"['".$data['LanguageFrom']."']",
"['".$data['LanguageTo']."']",
file_get_contents($from)
);
+
+ // merge data if target file exists
+ if (file_exists($to)) {
+
+ $message = _t('LangEditor.MERGED','Merged');
+
+ // get array of existing target
+ $existing_code = file_get_contents($to)." return \$lang;";
+ $existing_code = str_replace(
+ array('<?php','<?','?>','global $lang;'),
+ array('','','','$lang = array();'),
+ $existing_code
+ );
+ $existing_array = eval($existing_code);
+
+ // get array of new content
+ $new_code = $new_contents." return \$lang;";
+ $new_code = str_replace(
+ array('<?php','<?','?>','global $lang;'),
+ array('','','','$lang = array();'),
+ $new_code
+ );
+ $new_array = eval($new_code);
+
+ if(is_array($existing_array) && isset($existing_array[self::$currentLocale])
+ && is_array($new_array) && isset($new_array[self::$currentLocale]))
+ {
+ $new_array = array_replace_recursive($new_array, $existing_array);
+ }
+
+ $new_contents = "<?php\n\nglobal \$lang;\n\n";
+ foreach($new_array as $locale => $array_of_namespaces) {
+ foreach($array_of_namespaces as $namespace => $array_of_entities) {
+ foreach($array_of_entities as $entity => $translation) {
+ $new_contents .= "\$lang['$locale']['$namespace']['$entity'] = '".addslashes($translation)."';\n";
+ }
+ }
+ }
+
+ }
+
+ // write new content into target file
$fh = fopen($to,"w");
fwrite($fh, $new_contents);
fclose($fh);
- return $this->renderWith('LanguageList');
+
+ //$langs = $this->getLanguages();
+ //return $this->customise($langs)->renderWith('LanguageList');
+ return new SS_HTTPResponse($message,200);
}
}
View
25 css/lang_editor.css
@@ -5,21 +5,26 @@ div.entity_field {float:left;width:70%;}
#namespaces h3 {margin:10px 0;}
#namespaces h3 a {text-decoration:none;color:#666;font-size:14px;}
#left h4 {background:#ccc;padding:4px 0;text-align:center;font-size:12px;color:#333;}
-#available_languages {height:250px;overflow:auto;}
-#available_languages ul li {margin:4px 0;font-size:11px;}
-#available_languages ul li a {padding:4px 4px 4px 20px;text-decoration:none;display:block;}
-#available_languages ul li a:hover {background:#ddd;}
-#available_languages ul li a.current {background:#ccc;}
-#Form_CreateTranslationForm .field {float:none;width:90%;margin:10px 0 0 10px;border-bottom:1px solid #999;padding:4px 0;}
+#available_languages {height:80px;overflow:auto;}
+#available_modules {height:230px;overflow:auto;}
+#available_languages ul li,
+#available_modules ul li {margin:2px 0;font-size:11px;}
+#available_languages ul li a,
+#available_modules ul li a {padding:2px 2px 2px 20px;text-decoration:none;display:block;}
+#available_languages ul li a:hover,
+#available_modules ul li a:hover {background:#ddd;}
+#available_languages ul li a.current,
+#available_modules ul li a.current {background:#ccc;}
+#Form_CreateTranslationForm .field {float:none;width:90%;margin:5px 0 0 5px;padding:2px 0;}
#Form_CreateTranslationForm .field select {width:100% !important;float:none;display:block;}
#Form_CreateTranslationForm .field label.left {display:block;float:none;margin:0;font-size:11px;color:#333;}
-#Form_CreateTranslationForm .Actions {text-align:center;margin:10px auto;}
+#Form_CreateTranslationForm .Actions {text-align:center;margin:5px auto;}
#utility_bar {height:75px;background:#ccc;position:relative;padding:0 12px;}
-#utility_bar h2 {width:35%;line-height:70px;color:#444;float:left;}
-#namespace_dropdown {width:15%;float:left;line-height:70px;}
+#utility_bar h2 {width:50%;line-height:70px;color:#444;float:left;}
+#namespace_dropdown {width:25%;float:left;line-height:70px;}
#Namespace {font-size:12px;margin:0;}
#Namespace label {float:none;margin:0;display:none;}
-#search {width:30%;float:right;font-size:16px;margin-top:20px;}
+#search {width:25%;float:right;font-size:16px;margin-top:20px;}
#search input {width:150px;padding:6px 4px;border:1px solid #999;font-size:16px;color:#666;}
#search label {margin-right:10px;font-size:12px;}
#Form_TranslationForm .actions {text-align:left;margin:10px 0;float:left;}
View
32 javascript/lang_editor.js
@@ -1,29 +1,49 @@
(function($) {
$(function() {
- $('body').ajaxStart(function() {$('#ajax-loader').show()});
- $('body').ajaxStop(function() {$('#ajax-loader').hide()});
+ $('body').ajaxStart(function() {$('#ajax-loader').show();});
+ $('body').ajaxStop(function() {$('#ajax-loader').hide();});
$('#available_languages ul li a').live("click",function() {
$t = $(this);
$('#translations').load($t.attr('href'));
+ $('#available_modules').load($t.attr('href').replace("show", "updatemodules"));
+ $('#available_languages').load($t.attr('href').replace("show", "updatelanguages"));
+ $('#create_translation_form').load($t.attr('href').replace("show", "updatecreateform"));
return false;
});
+ $('#available_modules ul li a').live("click",function() {
+ $t = $(this);
+ $('#translations').load($t.attr('href'));
+ $('#available_modules').load($t.attr('href').replace("show", "updatemodules"));
+ $('#available_languages').load($t.attr('href').replace("show", "updatelanguages"));
+ $('#create_translation_form').load($t.attr('href').replace("show", "updatecreateform"));
+ return false;
+ });
+
$('#translations h3 a').livequery("click",function() {
$t = $(this);
$t.parents('h3').next('.namespace').slideDown();
});
- $('#Form_CreateTranslationForm').submit(function() {
+ $('#Form_CreateTranslationForm').live("submit",function() {
var $t = $(this);
+ var old_lang = $('#Form_CreateTranslationForm_LanguageFrom').val();
var new_lang = $('#Form_CreateTranslationForm_LanguageTo').val();
$.post(
$t.attr('action'),
$t.serialize(),
function(data) {
- $('#available_languages').html(data);
- $('#'+new_lang).click();
+ // display message
+ $('#message').show().html(data);
+ setTimeout(function() {
+ $('#message').fadeOut();
+ },3000);
+ // reload language list
+ $('#available_languages').load($('#'+old_lang).attr('href').replace("show", "updatelanguages"), function() {
+ $('#'+new_lang).click();
+ });
}
);
return false;
@@ -37,7 +57,7 @@ $(function() {
function(data) {
$('#message').show().html(data);
setTimeout(function() {
- $('#message').fadeOut()
+ $('#message').fadeOut();
},3000);
}
);
View
0 lang/_manifest_exclude
No changes.
View
19 lang/de_DE.php
@@ -0,0 +1,19 @@
+<?php
+
+global $lang;
+
+$lang['de_DE']['LangEditor']['MENUTITLE'] = 'Statische Übersetzung';
+$lang['de_DE']['LangEditor']['AVAILABLELANGUAGES'] = 'Vorhandene Sprachen';
+$lang['de_DE']['LangEditor']['AVAILABLEMODULES'] = 'Vorhandene Module';
+$lang['de_DE']['LangEditor']['CREATE'] = 'Erstellen';
+$lang['de_DE']['LangEditor']['CREATENEW'] = 'Neue Sprachdatei erzeugen';
+$lang['de_DE']['LangEditor']['EDITING'] = 'In Arbeit';
+$lang['de_DE']['LangEditor']['FILESNOTRIGHT'] = 'Die Ausgangssprache existiert nicht oder die Zielsprache existiert bereit.';
+$lang['de_DE']['LangEditor']['NAMESPACE'] = 'Namespace';
+$lang['de_DE']['LangEditor']['PLEASESELECT'] = 'bitte wählen';
+$lang['de_DE']['LangEditor']['SAVE'] = 'Speichern';
+$lang['de_DE']['LangEditor']['SAVED'] = 'Gespeichert';
+$lang['de_DE']['LangEditor']['SEARCH'] = 'Suchen';
+$lang['de_DE']['LangEditor']['SHOWALLNAMESPACES'] = 'Alle Namespaces anzeigen';
+$lang['de_DE']['LangEditor']['TRANSLATEFROM'] = 'Von';
+$lang['de_DE']['LangEditor']['TRANSLATETO'] = 'Nach';
View
19 lang/en_US.php
@@ -0,0 +1,19 @@
+<?php
+
+global $lang;
+
+$lang['en_US']['LangEditor']['MENUTITLE'] = 'Static Translator';
+$lang['en_US']['LangEditor']['AVAILABLELANGUAGES'] = 'Available languages';
+$lang['en_US']['LangEditor']['AVAILABLEMODULES'] = 'Available modules';
+$lang['en_US']['LangEditor']['CREATE'] = 'Create';
+$lang['en_US']['LangEditor']['CREATENEW'] = 'Create new translation file';
+$lang['en_US']['LangEditor']['EDITING'] = 'Editing';
+$lang['en_US']['LangEditor']['FILESNOTRIGHT'] = 'The from language does not exist, or the new language already exists!';
+$lang['en_US']['LangEditor']['NAMESPACE'] = 'Namespace';
+$lang['en_US']['LangEditor']['PLEASESELECT'] = 'Please select';
+$lang['en_US']['LangEditor']['SAVE'] = 'Save';
+$lang['en_US']['LangEditor']['SAVED'] = 'Saved';
+$lang['en_US']['LangEditor']['SEARCH'] = 'Search';
+$lang['en_US']['LangEditor']['SHOWALLNAMESPACES'] = 'Show all namespaces';
+$lang['en_US']['LangEditor']['TRANSLATEFROM'] = 'From';
+$lang['en_US']['LangEditor']['TRANSLATETO'] = 'To';
View
1 templates/Includes/CreateTranslationForm.ss
@@ -0,0 +1 @@
+$CreateTranslationForm
View
9 templates/Includes/LangEditor_left.ss
@@ -1,7 +1,14 @@
+<h4><% _t('LangEditor.AVAILABLEMODULES','Available modules') %></h4>
+<div id="available_modules">
+<% include ModuleList %>
+</div>
+
<h4><% _t('LangEditor.AVAILABLELANGUAGES','Available languages') %></h4>
<div id="available_languages">
<% include LanguageList %>
</div>
<h4><% _t('LangEditor.CREATENEW','Create new translation file') %></h4>
-$CreateTranslationForm
+<div id="create_translation_form">
+<% include CreateTranslationForm %>
+</div>
View
5 templates/Includes/ModuleList.ss
@@ -0,0 +1,5 @@
+<ul>
+ <% control Modules %>
+ <li><a id="$Name" href="$Link">$Name</a></li>
+ <% end_control %>
+</ul>
View
3 templates/Includes/Translations.ss
@@ -1,5 +1,5 @@
<div id="utility_bar">
- <h2><% _t('LangEditor.EDITING','Editing') %>: $SelectedLanguage [$SelectedLocale]</h2>
+ <h2><% _t('LangEditor.EDITING','Editing') %>: $SelectedModule, $SelectedLanguage [$SelectedLocale]</h2>
<div id="namespace_dropdown">$NamespaceDropdown.FieldHolder</div>
<div id="search"><label><% _t('LangEditor.SEARCH','Search') %></label><input type="text" value="" /></div>
</div>
@@ -19,6 +19,7 @@
<% end_control %>
</div>
<input type="hidden" name="SecurityID" value="$SecurityID" />
+ <input type="hidden" name="Module" value="$SelectedModule" />
<div class="actions">
<% control TranslationForm %>
<% control Actions %>

0 comments on commit dc83e89

Please sign in to comment.
Something went wrong with that request. Please try again.