问题描述
我正在尝试建立一种允许成员将字符串翻译成其他语言的方法.您可以在此处看到一个示例:翻译测试
I am trying to set up a way to allow members to translate strings into other languages. You can see an example here: TRANSLATIONS TEST
有人建议我为此使用php的本机gettext()函数,而不是我已经用来加载语言文件的函数:
Someone recommended that I use php's native gettext() function for this, instead of what I am already using to load the language files, which is this:
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.phpDreamPortal.english.php等
The strings are contained within a file that is named like so:ManageDPModules.english.phpDreamPortal.english.phpetc.
在任何php编辑器中打开这些文件时,它们看起来可能如下所示,并且可以包含许多$ txt变量:
These files can look like the following, when opened in any php editor, and can have many of these $txt variables:
<?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>".';
?>
我正在使用以下功能来保存翻译:
I am using the following function to save the translations:
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]',
'[\'$2\']',
);
// Convert the data back to normal.
$data = preg_replace($codes, $html, $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将如何提供帮助.如果没有每次都重新引导服务器,则无法更新文本目录.也许有人可以为我创建一个演示吗?
I fail to see how gettext will help out. There is no way to update the text catalog without rebooting the server every time. Maybe if someone can create a demo of this for me?
还希望它支持UTF-8.数据应该一致.
Also, would like it to support UTF-8. The data should be consistent.
那么这个实现有什么问题呢?为什么要使用gettext?
So what is wrong with this implementation?? Why use gettext?? How can it be used to improve translations to work for both UTF-8 and non UTF-8 language strings so that it can be translated.?
请注意,文件最终将需要重命名为:ManageDPModules.[language].php
,DreamPortal.[language].php
等,以便翻译生效.那么,目录在这方面将如何帮助我?如果要查看可能的END-RESULT翻译,可以下载位于这里,然后打开.german.php语言文件,查看成员在逐个文件的基础上提交语言后的外观.请注意,其中一些程序包具有UTF-8字符串,而有些则没有.软件包的文件名让您知道这一点.如果我还可以使其支持UTF-8,那就太好了,但这不是必需的.请注意,我不是在这里尝试创建完整的软件包.我只想创建一个languagefile.[language] .php,其中包含所有翻译后的字符串(我的代码已经做到了).
Please note, the files will eventually need to be renamed to: ManageDPModules.[language].php
, DreamPortal.[language].php
, etc., etc. in order for the translations to work. So, how would catalogs help me in this regard? If you want to see possible END-RESULT Translations, you can download a language package located here and open up the .german.php language files to see what it should look like after the member submits a language on a file by file basis. Noted that some of these packages have UTF-8 strings, and some do not. The filename of the packages let you know this. Would be nice if I can also make it support UTF-8, but it is not a requirement. Please note, I'm not trying to create complete packages here. I just want to create the languagefile.[language].php with all of the translated strings inside of them (which my code already does).
好的,我将为此提供ENTIRE index.php文件,以便您在进行翻译时可以确切地看到它的作用.这是 index.php 文件为此,您将需要一些英语文件: DreamPortal.english.php , ManageDPModules.english.php 和 DreamHelp.english-utf8.php .现在,为了了解这一点,您需要上载到服务器index.php,在index.php所在的位置创建一些文件夹,调用1英文,并在其中为您想要的每种其他语言创建一个文件夹(我做了2文件夹(西班牙语和法语),然后将3种语言文件上传到英语文件夹中.在浏览器中运行index.php,您将看到它正常工作.
OK, I will provide the ENTIRE index.php file for this so you can see what it does exactly when you do translations. Here is the index.php file for this and you'll need some english language files: DreamPortal.english.php, ManageDPModules.english.php, and DreamHelp.english-utf8.php. Now, in order to see this, you need to upload to a server, index.php, create a few folders where index.php is, call 1 english, and create a folder in there for each additional language you want (I did 2 folders, spanish and french), than upload the 3 language files into the english folder. Run index.php in your browser and you will see it working.
现在,如何通过这种SAME方法将gettext用于目录.我需要启用文件的在线翻译.我需要以相同样式创建翻译的PHP文件,即.english.php文件具有与.english.php
之前相同的PREFIX,并且我需要将文件名中的语言更改为为文件夹定义的相同语言姓名.在线翻译是唯一可用的方法.译者只需要专注于翻译字符串.他们不应该专注于安装程序,打包,重命名文件等.这使得此过程尽可能轻松,可以在线完成.而且我知道有一种方法可以做到这一点,即使是对UTF-8的支持也是如此.但是我正在使用目前我所知道的最佳方法.但是,在这种事情上,你们当中很多人比我聪明得多,所以我寻求你们的帮助.
Now, how could I use gettext for catalogs with this SAME approach. I need to enable online translation of files. I need to create PHP files of the translations in the SAME style that the .english.php files are with the same PREFIX that is before .english.php
, and I need to change the language within the filename to the same language defined for the folder name. Online translations is the ONLY method available. Translator's need to focus ONLY on translating the strings. They shouldn't be focusing on installing programs, packaging it up, renaming the files, etc. etc.. This makes this process as painless as possible allowing it to be done online. And I know there is a way to do this, and even for UTF-8 support. But I'm using the best method that I know how at the moment. But so many of you are MUCH smarter at this sort of thing than I am, so I ask for help from you guys.
有人可以向我展示更好的方法吗?像我在这个问题中给您的例子一样?
Is there anyone that can show me a better way? An example like the one that I have given you in this question?
我需要允许翻译人员在线进行翻译,并且还希望它支持UTF-8文件以及非UTF-8文件.设置上面提供的链接(翻译测试),以便翻译人员可以在线进行翻译不必担心其他任何事情,它会自动创建所需的文件.这与第一个.(点)后带有文件夹名称(代表语言)的语言的英语文件名相同,并且需要具有扩展名.php(就像在我当前正在使用的代码).因此,基本上,我需要对当前的index.php进行改编,以支持所有或大多数语言的UTF-8和非UTF-8,并被告知使用gettext()和目录文件将对此有所帮助.
I need to allow translations to be done ONLINE from translators, and would also like it to support UTF-8 files, as well as non UTF-8 files. I like the way I have it setup for the link provided above (TRANSLATIONS TEST) so that translator's can just do the translations online and not have to worry about anything else, and it would automatically create the files needed. Which would be the same as the english filename of the language with the folder name (representing the language) after the first . (dot) and it needs to have the extension .php (like it does in the code I am currently using). So basically, I need an adaption of the current index.php to support UTF-8 and non UTF-8 for all or most languages, and was told that using gettext() and catalog files would help with this.
正在寻找当前index.php的修改版本以使用gettext()来支持大多数(如果不是全部)语言和翻译.我为preg_replace进行的REGEX并不完全令人满意,因为在保存/提交翻译时,它似乎在双引号前面加了一个斜杠.因此,也许还需要对preg_replace进行改进.
Looking for a modified version of my current index.php to use gettext() in a way that it will support most, if not all, languages and translations. The REGEX I got going on for preg_replace isn't completely satisfactory because it seems to place a forward slash in front of double quotes when saving/submitting the translations. So perhaps an improvement on the preg_replace would be needed also.
此外,我还提供了一个完整的ACTUAL CODE示例.我希望有人用我提供给USE GETTEXT的CODE来更改此示例,并支持UTF-8.或实际上为我自己提供了一种实际方法.不是在寻找我可以自己找到的一堆链接!
I provided a complete example with ACTUAL CODE bytheway. I'd like for someone to alter this example, with the CODE that I provided to USE GETTEXT instead and support UTF-8. Or actually provide a ACTUAL METHOD for me to do this myself with. Not looking for a bunch of links that I can find on my own!
谢谢!
推荐答案
建议您使用gettext时,实际上建议您使用 gettext- like 翻译系统.由于助记符文本标记,您当前的代码很复杂.使用正则表达式进行编辑时遇到的麻烦是由于在其中摆弄变量而引起的.让我提出一些用于过渡目的的替代代码.
When you have been recommended to use gettext, it was actually an advise to use a gettext-like translation system. Your current code is complex because of mnemonic text indicies. And the trouble you got into with the regular expressions for editing is caused by fiddling with variables in there. Let me propose some alternative code for transitional purposes.
gettext的优点在于它使用了非干扰性的API.函数调用_()
非常简单,可以在不增加太多语法或代码膨胀的情况下彻底使用.比诸如getTextTrans('ABBR_TXT_ID')
之类的东西更可取.使用这样的助记符文本id是一个普遍的谬论.因为在实践中不需要频繁的改写,并且_("Raw english original text.")
具有相同的目的.但是,由于您已经有助记键,因此如果更改太多,请保留它们.这只是一个建议.
The beauty of gettext lies in its use of a non-obtrusive API. The function call _()
is simple enough to be thoroughly used without adding much syntax or code bloat. It's preferrable to things like getTextTrans('ABBR_TXT_ID')
. Using such mnemonic text ids is a widespread fallacy; because in practice there aren't frequent rewordings and _("Raw english original text.")
serves the same purpose. However, since you already have mnemonic keys in place, keep them if it's too much to change. This is just a recommendation.
您真正的问题是使用内联PHP表达式来构建翻译目标字符串.这就是为什么您的翻译编辑器的正则表达式变得不透明的原因.因此,我强烈建议使用静态字符串并提供占位符.翻译功能应负责处理它. (不必担心这里的微优化!)-例如,我将使用{$url_xy}
PHP/Smarty风格的占位符:
Your real problem is the use of inline PHP expressions to build up the translation target strings. They are why the regular expressions for your translation editor became opaque. Therefore I'd highly recommend to use static strings and provide placeholders. The translation function should be tasked with handling it. (Don't worry about microoptimizing here!) - I would use {$url_xy}
PHP/Smarty-style placeholders for example:
$txt['dp_who_forum'] = 'Viewing the forum index
of <a href="{$scripturl}?action=forum">{$forum_name}</a>.';
还有一个转换函数,该函数查找全局占位符表或参数($ context)以进行替换:
And a translation function that looks up a global placeholder table or params ($context) for replacing:
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;
}
可优化.但是通过这种方式,您可以使用静态助记符->文本或英语->文本的翻译数组集. 您只能在文本翻译编辑器形式的whaty中使用静态字符串.这些静态字符串按原样显示,您的翻译人员编辑英语文本,但不编辑任何{$placeholders}
.
Optimizable. But this way you can use a static mnemonic->text or english->text set of translation arrays. You only use static strings in your text-translation-editor-form thingy. Those static strings are shown as-is, and your translators edit the english text, but not any of the {$placeholders}
.
因此,用于翻译功能的代码不需要任何复杂的正则表达式(在这种情况下,它们就没有用)来匹配字符串和内联PHP变量.实际上,现在可以使用更简单的include()
和var_export()
组合了:
Hence your code for the translation feature won't need any of the complex regular expressions (in this case they are not useful) to match strings and inline PHP variables. In fact a much simpler include()
and var_export()
combination can now take its place:
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).';?>');
}
文件处理和其他当然需要进行自定义.但这仍然是一种更简单的方法.
Filehandling and whatnot needs to be customized of course. But still this is a simpler approach.
这将进一步允许您过渡到gettext变体之一作为后端.保留您的自定义包装函数__()
并使用例如Zend_Translate作为后端.这使您可以继续使用.php $ txt = array()翻译文件(或者,我认为是这样)或移至gettext样式的.mo/.po文件.这样做的好处是,与自制解决方案相比,它提供了丰富的工具支持.
And it would further allow you to transition to one of the gettext variations as backends. Keep your custom wrapper function __()
and use e.g. Zend_Translate as backend. This allows you to keep using your .php $txt=array() translation files (or I think so) or move to gettext-style .mo/.po files. The advantage of that being, that there is rich tool support in contrast to homebrew solutions.
无论如何,这就是您在主应用程序中使用这些内容的方式:
Anyway this is how you use the stuff in your main application:
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键移动到英语->外文翻译数组,但是从理论上讲,dvbs答案的任何后端都适用.现在您已经说过,本机gettext对您来说不是一个选择(对于非fastcgi PHP设置,内存不足是一个缺点).但是PHP的本机INTL功能可能会对您有所帮助.特别是 http://www.php.net/manual/zh/class.messageformatter .php 可能比我给您的简单{{var}}替换包装器有用.但是我从未使用过它,我认为Zend_Translate可能更有用.这些后端中的任何一个都可以特别赋予您字符集独立性.就我个人而言,无论如何我都会坚持使用UTF-8.但是,例如,每个gettext .mo/.po文件都可以具有自己的自定义字符集.
Moving from the short_txt keys to english->foreign text translation arrays would be advisable first, but in theory any of the backends from dvbs answer would be applicable. Now you already said that native gettext is not an option for you (for non-fastcgi PHP setups the memory resistance is a drawback). But PHPs native INTL features might be of help to you. In particular http://www.php.net/manual/en/class.messageformatter.php might be more useful than the simple-minded {$var} replacement wrapper I gave you. But I've never used it, and I think Zend_Translate is likely more useful. In particular can any of those backends give you charset independence. Personally I'd just stick to UTF-8, no matter what. But gettext .mo/.po files can each have their own custom charset for example.
这篇关于使用gettext如何在这里为我提供帮助?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!