2011-11-07 67 views
12

我正在开发一个多语言的PHP Web应用程序,并且我需要使用gettext翻译很长的( - )文本。这些是电子邮件模板(通常很短,但仍然有几行)和部分视图模板(较长的描述性文本块)。这些文本会包含一些简单的HTML(例如强调大胆/倾斜的东西,可能是链接在这里或那里)。模板是捕获输出的PHP脚本。用gettext翻译更长的文本(视图和电子邮件模板)

问题是,gettext对于处理更长的文本看起来很笨拙。与短文本相比,更长的文本通常会有更多更改 - 我可以更改msgid并确保在所有翻译中进行更新(可能需要很多工作,并且在msgid很长时很容易出错),或者我可以保留msgid保持不变并仅修改翻译(这会在模板中留下误导性的过时文本)。另外,我也看到了在gettext字符串中包含HTML的建议,但是避免它会将单个自然文本分成许多块,这将成为翻译和重组的更大的噩梦,而且我也看到了一些建议不需要将gettext字符串分割成单独的msgids。

我看到的另一种方法是忽略这些较长文本的gettext,并将每个语言环境的外部子模板中的这些块分开,并仅包含当前语言环境的一个。缺点是我将gettext.po文件与位于完全不同位置的单独模板之间的翻译分开。

由于此应用程序将在未来用作其他应用程序的起点,因此我试图从长远角度提出最佳方法。在这种情况下,我需要一些关于最佳实践的建议。你是如何执行类似案件的?什么原来工作,什么是一个坏主意?

+1

相关:[如何在对大文本值进行小编辑时有效地使用gettext PO文件](http://stackoverflow.com/questions/2966026/),[在使用gettext和gettext时合并键和全文。 po文件](http://stackoverflow.com/questions/15743919/),[它是一个好主意的消息ID是英文文本?](http://stackoverflow.com/questions/216478/), [我可以自动更新gettext的.po文件中的msgids以进行微不足道的文本更改吗?](http://stackoverflow.com/questions/8288050/) – ento

回答

9

这是我使用的工作流程,在一个非常重贩卖的网站,有关于风格的文本内容数十长上下的块,翻译成六种语言:

  1. 选择一个基于文本的标记语言(我们用Markdown
  2. 对于长字符串,使用固定的消息ID,如“About_page_intro_markdown”中指出:
    • 描述文本的意图
    • 清楚地表明,这将是解释在降价格式
  3. 有我们的应用中呈现“* _markdown”字符串适当,确保只允许少数安全的HTML标签
  4. 建立翻译的工具:
    • 展示他们自己的降价在实时渲染(有点像Markdown dingus
    • 很容易让他们看到的文字,现在权威的基础语言翻译(因为这不再是msgid
  5. 教翻译如何使用新的工作流程此工作流程的

优点:

  • 由于翻译在一个安全的更高级别的编辑信息ID不改变所有的时间
  • 语法,很难搞定HTML
  • 非技术翻译人员发现使用Markdown编写起来非常简单,而不是HTML
这个工作流程的个

缺点:

  • 有静态不变的消息ID是指在文本变化需要带外(我们会做反正只要文本可以提高人们对音调或重点题)
  • 传输

我很满意这个工作流程为我们的网站运行的方式,并且绝对推荐它,并再次使用它。开始需要几天的时间,但建立,培训和发布很容易。

希望这会有所帮助,并祝您的项目顺利。

+0

您的方法非常有趣,但我有疑问。这种方法完全独立于gettext还是打算使用它?如果它打算使用gettext。连接在哪里?可能我错过了一些东西。 – lordscales91

+0

@ lordscales91这个工作流程可以在gettext或任何等效系统下正常工作 - 只要您构建第3步和第4步中描述的附加工具即可。 – Anirvan

3

gettext并非真的专为翻译大量文本而设计。

fwiw我已经在gettext字符串中包含了基本的HTML(strong,a等),因为我确信我们的翻译人员知道他们在做什么(大部分是正确的),并且翻译会被很好地测试。

我已经尝试了将文本分解为每段一个字符串的方法。粗略地说,如果在文本中间有一段英文,看起来很奇怪。如果其中一个字符串发生了变化,这意味着在发布新版本之前我们不得不等待翻译,这已经减慢了我们的速度。另一方面,翻译人员很容易看到文本的哪一部分发生了变化。这种方法适用于我尝试过的一个应用程序。

将某些文本分割到外部位置也起作用,但它导致了管理开销,而不是仅仅是一个.po文件或两个文件,还有一大堆其他文本必须与英文版进行手动比较并更新因此。如果您记得向翻译人员提供笔记,解释英文版本中的差异,那么这是可行的。

我自己仍然没有出售任何一种方法。

5

我刚刚遇到了这个问题,我相信我以优雅的方式解决了这个问题。

问题:我们想在PHP中使用Gettext,并使用主要语言字符串作为键翻译。但是,对于大块HTML(包括h1,h2,p,a等),我需要:

  • 为每个包含内容的标记创建一个翻译。

  • 将与标签的整个块一个翻译。

既不这些选项吸引了我,所以这是我做过什么:

  • 保持简单的字符串(“OK”,“添加”,“确认”,“我真棒应用程序”)作为定期获取Gettext .po条目,原始文本为关键字
  • 用markdown写入内容(大文本块),并将它们保存在文件中。 实施例的文件将是/homepage/content.md(初级/源文本),/homepage/content.da-DK.md/homepage/content.de-DE.md

  • 收件其获取内容文件(当前区域)并解析它的类。然后我用它喜欢:

    <?=Template::getContent("homepage/content")?>

然而,有关动态大文本是什么?简单。使用模板引擎。我决定在Smarty,并在我的Template类中使用它。

我现在可以使用模板逻辑.. 内降价!这真棒吗?!

随后而来的棘手的部分..

对于内容好看,有时你需要以不同的结构化你的HTML。考虑下面有3个“功能框”的广告系列区域。简单的解决方案:为该活动区域提供一个文件,并为每个的3个箱子提供一个文件。

但我可以做得比这更好。

我写了一个快速块解析器,所以我会将所有内容写入一个文件,然后分别渲染每个块。

示例文件:

[block campaign] 
Buy this now! 
============= 

Blaaaah... And a smarty tag: {$cool} 
[/block] 

[block feature 1] 
Feature 1 
--------- 

asdasd you get it.. 
[/block] 

[block feature 2] ... 

这是我会怎样使它们在标记:

<?php 
// At the top of the document... 

// Class handles locale. :) 
$template = Template::getContent("homepage/content", [ 
    "cool" => "Smarty variable! AWESOME!" 
]); 
?> 

... 

<title><?=_("My Awesome App")?></title>  

... 

<div class="hero"> 
    <!-- Template data already processed! :) --> 
    <?=$template->renderBlock("campaign")?> 
</div> 
<div class="featurebox"> 
    <?=$template->renderBlock("feature 1")?> 
</div> 
<div class="featurebox"> 
    <?=$template->renderBlock("feature 2")?> 
</div> 

恐怕我不能提供任何的源代码,因为这是为一个公司项目,但我希望你明白。