使用gettext翻译较长的文本(视图和电子邮件模板)

时间:2011-11-07 12:00:23

标签: email templates localization gettext longtext

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

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

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

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

3 个答案:

答案 0 :(得分:10)

这是我使用的工作流程,在一个人口密集的网站上,该网站有大约数十个长篇版本的文本内容块,翻译成六种语言:

  1. 选择基于文本的标记语言(我们使用Markdown
  2. 对于长字符串,请使用“About_page_intro_markdown”等固定消息ID:
    • 描述了文本的意图
    • 明确表示将以降价格式解释
  3. 让我们的应用正确呈现“* _markdown”字符串,确保只允许一些安全的HTML标记
  4. 为翻译人员构建一个工具:
    • 向他们展示了他们实时渲染的Markdown(有点像Markdown dingus
    • 让他们可以轻松查看文本的现在权威的基本语言翻译(因为它不再在msgid中)
  5. 教译员如何使用新的工作流程
  6. 此工作流程的优点:

    • 消息ID不会一直更改
    • 因为翻译人员正在使用安全的更高级语法进行编辑,所以很难搞乱HTML
    • 非技术翻译人员发现使用Markdown编写文章非常容易,而不是HTML

    此工作流程的缺点:

    • 拥有静态不变的消息ID意味着文本中的更改需要在带外传输(我们无论如何都会这样做,因为长文本会引起关于语气或重点的问题)

    我对这个工作流程为我们的网站运行的方式非常满意,并且绝对会推荐它,并再次使用它。开始花了几天时间,但是很容易建立,训练和发射。

    希望这会有所帮助,祝你的项目好运。

答案 1 :(得分: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&#34;功能框的广告系列区域&#34;在它下面。简单的解决方案:为广告系列区域提供一个文件,为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>

我担心我无法提供任何源代码,因为这是针对公司项目的,但我希望你明白这一点。

答案 2 :(得分:3)

gettext并非真正用于翻译大块文本。

fwiw我在gettext字符串中包含了基本HTML(强,等等),因为我相信我们的译员知道他们在做什么(大多数是正确的),并且翻译会得到很好的测试。

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

将一些文本拆分到外部位置也有效,但它导致管理开销,而不仅仅是一个.po文件,还有一大堆其他文本必须手动与英文版本进行比较并相应更新。如果您记得向译员提供说明,说明英语版本的不同之处和差异,这是可行的。

我自己仍未以任何一种方式出售。