一个不同的方法来翻译网络应用程序

3

我曾经制作过几个支持多语言的网站和应用程序,其中我使用了语言XML文件和代码中的关键词。但是对于我的Web应用程序来说,我认为这种方法很糟糕。我喜欢阅读和理解我的HTML代码。这段代码没有任何意义:

<h1><?= translate('main_headline'); ?></h1>

一开始看起来很不错,但最终程序员们却变得不开心,因为现在添加新功能的过程总是需要不断地将东西放入XML中。

我的解决方案是(我刚刚写了一个简单的PHP测试解析器,你觉得这个在大型项目上能行吗?)

我以英语作为基础语言,这是我的源文件外观:

<h1>{{ I love colors }}</h1>

我的解析器将使用文本(真实文本)作为字典数组的关键字。在这个例子中,我将从美式英语翻译为英式英语。

$dictionary['I love colors']['en_GB'] = 'I love colours'

我的基本语言已经在源文件中,不需要字典。

除了缓存、回退、字典存储等方面,还有很多需要考虑的地方。您认为它能在大型项目中运行吗?我是否有什么没考虑到的地方?


这种类型的字典被phpBB成功使用(尽管没有解析方面的功能)。然而,每种语言应该有一个字典文件,这样如果你需要en_GB,你就加载它,(1)避免无谓地加载20种语言,(2)在访问字典时不需要将其作为键。 - Alexis Wilke
5个回答

4
这种方法的一个缺陷是,应用程序的两个不同部分可能需要相同单词/短语的不同翻译。最明显的例子是同形异义词,例如“close”(附近)和“close”(关闭),但还有其他可能性。
一个人为的短语示例是:
在一个部分,“我喜欢我的颜色”只是指字面上的颜色。 在另一个部分,它意味着“我爱我的国旗”。
应该:
$dictionary['I love my colors']['es_ES']

“我喜欢我的颜色”和“我喜欢我的旗帜”都可以,但需要同时包含两者。

因此,在消息目录中通常使用唯一的ID或行号。


我认为他并不建议动态翻译每个单词。人工会手动翻译每个短语并硬编码这些翻译。 - Alexander Bird
@Thr4wn,我知道他没有使用自动翻译。正如我所说,他的消息目录存在问题,因为它只考虑了原始文本。如果应用程序的两个部分使用相同的文本来完成非常不同的任务,则会失败。Jochen的解决方案很好,因为它为每条消息提供了唯一的ID。其他解决方案(例如GNU gettext)使用原始行号。 - Matthew Flaschen
啊,我现在明白你的意思了。 - Alexander Bird
我不是狂热的唯一标识符粉丝,因为它会搞乱源代码。我正在考虑使用命名空间(基于URL或页面)来解决这个问题。这也将使解析器更快。 - Emil

1

一些考虑和想法。

  • 尽量减少短语重用。我的经验是这样做可以更容易地维护翻译。

  • 语法必须是语言无关的,因为您可能会翻译 PHP、JS、HTML 等具有自己文件类型的内容。换句话说,不仅需要解析 PHP 模板,.js 文件中也可能包含文本。

    {{ <img src="heading-en.png" alt="Heading" /> }}
    alert('{{ some text }}');
    
  • 上面的 alert 示例,如果翻译文本中包含了一个 ',则会出现问题,应该以某种方式处理。

  • 必须以某种方式允许翻译中的变量数据。请考虑下面的示例。

    {{ <?= $num ?> apples cost <span class="price"><?= $price ?></span> with <?= $discount ?>% discount }}
    

    这可能不太好工作,或者至少不允许变量名称更改或内联表达式。下面的示例会更好一些。

    {{
        %num% 苹果售价为 <span class="price">%price%</span>,享受 %discount%% 的折扣
        } num:<?= $num ?>
        , price$:<?= $price*$discount ?>
        , discount:<?= round($discount*100) ?>
    }
    

    ..其中 price$ 可能暗示它是一个价格,并转换为正确的货币。

  • 应该处理货币。

只是想到了一些事情。祝你好运 ;-)


0

我更喜欢使用虚构的标签来处理这种事情,这样我就可以包含上下文和意义的注释,这些对翻译者非常有用。例如:

<h1><l10n id="blah" notes="This is a header for a section on blah blah, title case">Blah Blah</l10n></h1>

同样地,您可以使用虚构的属性来替代alttitle文本。

但是,您需要注意不同的上下文(HTML,<script><style>,PHP,各种模板语言等)。您还需要注意单词顺序和性别问题,但这些都是标准的L10N问题。

然后,您可以将所有翻译文件预处理到单独的目录中(每种语言一个目录),避免实时生成翻译的开销。


0

是的,这是一个不错的方法。

我们使用类似于以下格式的代码: ||4332||我喜欢颜色||

然后你只需要解析文件,提取所有的ID(4332),并在数据库中查找相应的翻译即可。


你是如何跟踪所有的ID的? - Markus Hedlund

0

编辑:其他人的回答比我更好 :)

我不知道第二个选项存在什么问题(但我也没有使用 I18N 的经验)。

我唯一能想到的潜在问题是可逆性。如果有人返回并更改文本为“我喜欢颜色”,则必须始终确保他们返回到翻译,并更改英文键。然而,您正在进行 i18n 说明已经有人的工作是处理翻译的乏味部分,因此我不认为这会成为问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接