如何使用gettext帮助我?

SoL*_*oST 7 php gettext internationalization

我正在尝试设置一种方法,允许成员将字符串翻译成其他语言.你可以在这里看到一个例子: TRANSLATIONS TEST

有人建议我使用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;
}
Run Code Online (Sandbox Code Playgroud)

字符串包含在一个文件中,其名称如下: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 &quot;<a href="' . $scripturl . '?page=%1$s">%2$s</a>&quot;.'; 
?>
Run Code Online (Sandbox Code Playgroud)

我使用以下函数来保存翻译:

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();
} 
Run Code Online (Sandbox Code Playgroud)

语言功能:

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>';

}
Run Code Online (Sandbox Code Playgroud)

我没有看到gettext将如何帮助.如果不每次都重新启动服务器,就无法更新文本目录.也许如果有人可以为我创建这个演示?

此外,希望它支持UTF-8.数据应该是一致的.

那么这个实现有什么问题?为什么要使用gettext?如何使用它来改进翻译以适用于UTF-8和非UTF-8语言字符串,以便进行翻译.

编辑: 请注意,这些文件将最终需要被重命名为: ManageDPModules.[language].php,DreamPortal.[language].php为了等,等,为翻译工作.那么,目录如何在这方面帮助我呢?如果您想查看可能的END-RESULT翻译,可以下载此处的语言包并打开.german.php语言文件,看看成员在逐个文件的基础上提交语言后应该是什么样子.注意到其中一些包具有UTF-8字符串,而另一些则没有.包的文件名让你知道这一点.如果我也能支持UTF-8会很好,但这不是必需的.请注意,我不打算在这里创建完整的包.我只想创建语言文件.[language] .php,其中包含所有已翻译的字符串(我的代码已经完成).

好的,我将为此提供ENTIRE index.php文件,以便您在翻译时可以看到它的确切功能.这是index.php文件,你需要一些英文文件:DreamPortal.english.php,ManageDPModules.english.phpDreamHelp.english-utf8.php.现在,为了看到这个,你需要上传到服务器,index.php,创建一些index.php所在的文件夹,调用1英文,并在那里为你想要的每种其他语言创建一个文件夹(我做了2文件夹,西班牙语和法语),而不是将3种语言文件上传到英文文件夹中.在浏览器中运行index.php,您将看到它正常工作.

现在,我如何使用此SAME方法将gettext用于目录.我需要启用文件的在线翻译.我需要以SAME样式创建翻译的PHP文件.english.php文件与之前的PREFIX相同.english.php,我需要将文件名中的语言更改为为文件夹名称定义的相同语言.在线翻译是唯一可用的方法.译者需要专注于翻译字符串.他们不应该专注于安装程序,打包它们,重命名文件等等.这使得这个过程尽可能轻松,允许它在线完成.而且我知道有一种方法可以做到这一点,甚至可以支持UTF-8.但我现在正在使用我所知道的最好的方法.但是你们这么多人在这方面比我更聪明,所以我向你们寻求帮助.

有没有人可以告诉我更好的方法?像我在这个问题上给你的一个例子?

我需要允许翻译人员在线完成翻译,并且还希望它支持UTF-8文件以及非UTF-8文件. 我喜欢我为上面提供的链接(翻译测试)设置的方式,以便翻译人员可以在线进行翻译而不必担心其他任何事情,并且它会自动创建所需的文件.这与第一个文件夹名称(代表语言)的语言的英文文件名相同.(点),它需要扩展名.php(就像我目前使用的代码中一样).所以基本上,我需要修改当前的index.php以支持所有或大多数语言的UTF-8和非UTF-8,并且被告知使用gettext()和目录文件将有助于此.

寻找我当前index.php的修改版本以使用gettext(),它将支持大多数(如果不是全部)语言和翻译.我为preg_replace进行的REGEX并不完全令人满意,因为它在保存/提交翻译时似乎在双引号前放置了正斜杠.因此,也许还需要对preg_replace进行改进.

我提供了一个完整的示例,其中包含了实际代码.我希望有人能够改变这个例子,使用我提供给USE GETTEXT的CODE并支持UTF-8.或者实际上为我自己提供了一个实际的方法.没有找到我自己可以找到的一堆链接!

谢谢!

dvb*_*dvb 13

为什么重新发明轮子?也许我不明白,但我很确定你以前做过的事情已经完成了.

只需使用众多现有解决方案中的一种即可.

  • 访问他们每个人并过滤掉不相关的项目
  • 了解其余部分之间的差异,并选择最适合您的部分
  • 根据现有项目继续开发和定制您自己的需求
  • 如果您发现了错误,或者如果您认为原始项目将从您的添加内容中获益,请与作者联系并通知他

在做出决定时,需要考虑以下事项:

  • 项目使用的语言
  • 能够扩展,添加功能并根据您自己的需求进行定制
  • 这是服务吗?或者您可以在自己的服务器上下载和使用的开源软件
  • 它是否支持复数的翻译?
  • 可用于此项目的社区和资源
  • 它是否还附带了您所要求的基于Web的UI?

这是一些(随机排序):

祝好运!

更新:谢谢,El Yobo.我已将此标记为社区维基,如果他找到其他内容,欢迎任何人编辑或回复其他项目.


mar*_*rio 6

当你被推荐使用gettext,它实际上是使用一个提醒gettext- 翻译系统.由于助记符文本指示,您当前的代码很复杂.你使用正则表达式进行编辑所遇到的麻烦是由于在那里摆弄变量引起的.让我为过渡目的提出一些替代代码.

gettext的优点在于它使用了非突兀的API.函数调用_()很简单,可以在不添加太多语法或代码膨胀的情况下彻底使用.它更像是喜欢的东西getTextTrans('ABBR_TXT_ID').使用这样的助记符文本ID是一种普遍的谬误; 因为在实践中没有频繁的重新措辞,并且_("Raw english original text.") 服务于同一目的.但是,由于您已经安装了助记键,因此如果更改太多,请保留它们.这只是一个建议.

您真正的问题是使用内联PHP表达式来构建转换目标字符串.这就是为什么翻译编辑器的正则表达式变得不透明的原因.因此,我强烈建议使用静态字符串并提供占位符.翻译功能的任务是处理它.(不要担心这里的微优化!) - 我会使用{$url_xy}PHP/Smarty风格的占位符,例如:

$txt['dp_who_forum'] = 'Viewing the forum index
of <a href="{$scripturl}?action=forum">{$forum_name}</a>.'; 
Run Code Online (Sandbox Code Playgroud)

以及用于查找全局占位符表或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;
}
Run Code Online (Sandbox Code Playgroud)

优化的.但是这样你可以使用静态助记符 - >文本或英语 - >翻译数组的文本集.您只在文本翻译编辑器形式中使用静态字符串.那些静态字符串按原样显示,您的翻译人员编辑英文文本,但不能编辑任何英文文本{$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).';?>');
}
Run Code Online (Sandbox Code Playgroud)

当然,文件处理和诸如此类需要定制.但这仍然是一种更简单的方法.

它还可以让您转换为其中一个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..."));
Run Code Online (Sandbox Code Playgroud)

首先建议从short_txt键移动到英语 - >外语文本翻译数组,但理论上任何来自dvbs的后端都是适用的.现在你已经说过本机gettext不是你的选择(对于非fastcgi PHP设置,内存阻力是一个缺点).但PHP本机INTL功能可能对您有所帮助.特别是http://www.php.net/manual/en/class.messageformatter.php可能比我给你的简单的{$ var}替换包装更有用.但我从来没有使用它,我认为Zend_Translate可能更有用.特别是任何这些后端都可以让你拥有charset独立性.就个人而言,无论怎样,我都会坚持使用UTF-8.但gettext .mo/.po文件可以各自拥有自己的自定义字符集.