有人建议我使用PHP的本机gettext()函数,而不是我已经用来加载语言文件,这是:
function loadLanguageFile($language,$file) { $temp = array(); $data = file_get_contents('./'.$language.'/'.$file.'.'.$language.'.PHP'); $codes = array ( '/(\'\s*\.\s*\$)(.+?)(\s*\.\s*\')/','/(=\s*\$)(.+?)(\s*\.\s*\')/','/(\'\s*\.\s*\$)(.+?)(;)/','/(\[\')(.+?)(\'\])/','/<\?PHP/s','/\?>/s','/<\?/s' ); $html = array ( '{$2}','= \'{$2}','{$2}\';','[$2]','',); // Since we don't have the values for the vars. $data = preg_replace($codes,$html,$data); // We must change this because they are global. $data = str_replace('$txt','$langEditor_txt',$data); $data = str_replace('$helptxt','$langEditor_helptxt',$data); eval($data); if (isset($langEditor_txt)) { $temp['txt'] = $langEditor_txt; unset($GLOBALS['langEditor_txt']); } if (isset($langEditor_helptxt)) { $temp['helptxt'] = $langEditor_helptxt; unset($GLOBALS['langEditor_helptxt']); } return $temp; }
字符串包含在一个名为的文件中:
ManageDPModules.english.PHP
DreamPortal.english.PHP
等等
当在任何PHP编辑器中打开时,这些文件看起来如下所示,并且可以包含许多这些$txt变量:
<?PHP // Dream Portal (c) 2009-2010 Dream Portal Team // DreamPortal.english.PHP; @1.1 global $scripturl,$context; // General Strings $txt['forum'] = 'Forum'; $txt['dream_portal'] = 'Dream Portal'; $txt['dp_core_modules'] = 'Collapse or Expand this Module'; $txt['dp_who_forum'] = 'Viewing the forum index of <a href="' . $scripturl . '?action=forum">' . $context['forum_name'] . '</a>.'; $txt['dp_who_portal'] = 'Viewing the portal index of <a href="' . $scripturl . '">' . $context['forum_name'] . '</a>.'; $txt['dp_who_page'] = 'Viewing the page "<a href="' . $scripturl . '?page=%1$s">%2$s</a>".'; ?>
我使用以下函数来保存翻译:
function langSave($lang,$file) { // We just don't get values from the form,they have to exist in the english files to be taken serIoUsly. $default = loadLanguageFile('english',$file); if ($default['txt']) { foreach ($default['txt'] as $key=>$string) { if (isset($_REQUEST['txt'.$key]) && str_replace(' ',$_REQUEST['txt'.$key]) != '') { $data.='$txt[\''.$key.'\'] = \''.str_replace("'","\'",$_REQUEST['txt'.$key]).'\';'."\n"; } } } if ($default['helptxt']) { foreach ($default['helptxt'] as $key=>$string) { if (isset($_REQUEST['helptxt'.$key]) && str_replace(' ',$_REQUEST['helptxt'.$key]) != '') { $data.='$helptxt[\''.$key.'\'] = \''.str_replace("'",$_REQUEST['helptxt'.$key]).'\';'."\n"; } } } if (isset($data)) { $codes = array (// '' . $test . ' '/(\{)(.+?)(\})/','/(\'\' \. \$)(.+?)( \. \')/','/(\' \. \$)(.+?)( \. \'\')/','/(\[)(.+?)(\])/',); $html = array ( '\' . \$$2 . \'','\$$2 . \'','\' . \$$2','[\'$2\']',); // Convert the data back to normal. $data = preg_replace($codes,$data); $data = '<?PHP'."\n".$data.'?>'; file_put_contents('./'.$lang.'/'.$file.'.'.$lang.'.PHP',$data); } languageHome(); }
语言功能:
function languageHome() { $languages = loadLanguageList(); echo ' Language List <table>'; foreach ($languages as $language) { echo ' <tr> <td> '.$language.' </td> <td> <a href="index.PHP?op=langView&lang='.$language.'">View</a> </td> </tr>'; } echo ' </table>'; }
我没有看到gettext将如何帮助.如果不每次都重新启动服务器,都无法更新文本目录.也许有人可以为我创建一个这样的演示?
此外,希望它支持UTF-8.数据应该是一致的.
那么这个实现有什么问题?为什么要使用gettext?如何使用它来改进翻译以适用于UTF-8和非UTF-8语言字符串,以便进行翻译.
编辑:
请注意,文件最终需要重命名为:ManageDPModules.[语言] .PHP,DreamPortal.[语言] .PHP等,以便翻译工作.那么,目录如何在这方面帮助我呢?如果您想查看可能的END-RESULT翻译,可以下载位于here的语言包并打开.german.PHP语言文件,以查看成员在逐个文件的基础上提交语言后的样子.注意到其中一些包具有UTF-8字符串,而另一些则没有.包的文件名让你知道这一点.如果我也能支持UTF-8会很好,但这不是必需的.请注意,我不打算在这里创建完整的包.我只想创建语言文件.[language] .PHP,其中包含所有已翻译的字符串(我的代码已经完成).
好的,我将为此提供ENTIRE index.PHP文件,以便您在翻译时看到它的确切作用.这里是index.php文件,你需要一些英文语言文件:DreamPortal.english.php,ManageDPModules.english.php和DreamHelp.english-utf8.php.现在,为了看到这个,你需要上传到服务器,index.PHP,创建一些文件夹,其中索引.PHP,调用1英语,并在那里为你想要的每种语言创建一个文件夹(我做了2个文件夹,西班牙语和法语),而不是将3个语言文件上传到英语文件夹中.在浏览器中运行index.PHP,您将看到它正常工作.
现在,我如何使用此SAME方法将gettext用于目录.我需要启用文件的在线翻译.我需要创建SAME样式的翻译PHP文件,其中.english.PHP文件与.english.PHP之前的PREFIX相同,我需要将文件名中的语言更改为为其定义的相同语言文件夹名称.在线翻译是唯一可用的方法.译者需要专注于翻译字符串.他们不应该专注于安装程序,打包程序,重命名文件等等.这使得这个过程尽可能轻松,允许它在线完成.而且我知道有一种方法可以做到这一点,甚至可以支持UTF-8.但我现在正在使用我所知道的最好的方法.但是你们这么多人在这方面比我更聪明,所以我向你们寻求帮助.
有没有人可以告诉我更好的方法?像我在这个问题上给你的一个例子?
我需要允许翻译人员在线完成翻译,并且还希望它支持UTF-8文件以及非UTF-8文件.我喜欢我为上面提供的链接(TRANSLATIONS TEST)设置的方式,以便翻译人员可以在线进行翻译而不必担心其他任何事情,并且它会自动创建所需的文件.这与第一个文件夹名称(代表语言)的语言的英文文件名相同. (点),它需要扩展名.PHP(就像我目前使用的代码中一样).所以基本上,我需要对当前的index.PHP进行调整以支持所有或大多数语言的UTF-8和非UTF-8,并且被告知使用gettext()和目录文件将有助于此.
寻找我当前index.PHP的修改版本,以便以支持大多数(如果不是全部)语言和翻译的方式使用gettext().我为preg_replace进行的REGEX并不完全令人满意,因为它在保存/提交翻译时似乎在双引号前放置了正斜杠.因此,也许还需要对preg_replace进行改进.
我提供了一个完整的示例,其中包括bytheway的ACTUAL CODE.我希望有人能够改变这个例子,使用我提供给USE GETTEXT的CODE并支持UTF-8.或者实际上为我自己提供了一个实际的方法.没有找到我自己能找到的一堆链接!
谢谢!
gettext的优点在于它使用了非突兀的API.函数调用_()非常简单,可以在不添加太多语法或代码膨胀的情况下彻底使用.它更适合像getTextTrans(‘ABBR_TXT_ID’)这样的东西.使用这种助记符文本ID是一种普遍的谬误;因为在实践中没有频繁的重写和_(“原始英文原文”.)用于相同的目的.但是,由于您已经安装了助记键,因此如果更改太多,请保留它们.这只是一个建议.
您真正的问题是使用内联PHP表达式来构建转换目标字符串.这就是为什么翻译编辑器的正则表达式变得不透明的原因.因此,我强烈建议使用静态字符串并提供占位符.翻译功能的任务是处理它. (不要担心这里的微优化!) – 我会使用{$url_xy} PHP / Smarty风格的占位符,例如:
$txt['dp_who_forum'] = 'Viewing the forum index of <a href="{$scripturl}?action=forum">{$forum_name}</a>.';
以及用于查找全局占位符表或params($context)以进行替换的翻译函数:
function __($text,$params=array()) { global $txt,$txt_placeholders; if (isset($txt[$text])) { $text = $txt[$text]; } if (strpos($text,'{$')) { $params = array_merge($params,$txt_placeholders); $text= preg_replace("/\{\$(\w+)\}/e","$params['$1']",$text); } return $text; }
优化的.但是这样您就可以使用静态助记符 – >文本或英语 – >文本集翻译数组.您只在文本翻译编辑器形式中使用静态字符串.这些静态字符串按原样显示,您的翻译人员编辑英文文本,但不编辑任何{$placeholders}.
因此,您的转换功能代码不需要任何复杂的正则表达式(在这种情况下它们没用)来匹配字符串和内联PHP变量.事实上,更简单的include()和var_export()组合现在可以取而代之:
function langSave($lang,$file) { $txt = array(); include($file); // assuming it contains a simple $txt = array(... foreach ($txt as $key=>$string) { $txt[$key] = $_REQUEST["txt$key"]; } file_put_contents($file,"<?PHP\n\$txt =".var_export($txt,1).';?>'); }
当然,文件处理和诸如此类需要定制.但这仍然是一种更简单的方法.
它还可以让您转换为其中一个gettext变体作为后端.保留自定义包装函数__()并使用例如Zend_Translate作为后端.这允许您继续使用.PHP $txt = array()翻译文件(或者我认为是这样)或移动到gettext样式的.mo / .po文件.这样做的好处是,与自制软件解决方案相比,有丰富的工具支持.
无论如何,这是你在主应用程序中使用这些东西的方式:
print "<a href='...'>" . __("link_text") . "</a>"; print __("dp_forum_link"); // uses e.g. $txt_placeholder["scripturl"] print __("dp_param_link",array("scripturl"=>"http://override..."));
首先建议从short_txt键移动到english->外部文本翻译数组,但理论上dvbs中的任何后端都是适用的.现在你已经说过本机gettext不是你的选择(对于非fastcgi PHP设置,内存阻力是一个缺点).但PHP本机INTL功能可能对您有所帮助.特别是http://www.php.net/manual/en/class.messageformatter.php可能比我给你的简单的{$var}替换包装更有用.但我从来没有使用它,我认为Zend_Translate可能更有用.特别是任何这些后端都可以让你拥有charset独立性.就个人而言,无论怎样,我都会坚持使用UTF-8.但gettext .mo / .po文件可以各自拥有自己的自定义字符集.