如何找到丢失或未使用的翻译信息

3.4 版本
维护中的版本

当维护程序或bundle时,你可能要添加或删除翻译信息(messages),然后却忘了更新信息目录(catalogues)。debug:translation 命令能帮你找到这些丢失的或未使用的翻译信息。

得益于“信息提取器”(message extractor),这个命令将侦测到Twig模板中翻译的标签(tags)或调节器(filters):

1
2
3
4
5
6
7
{% trans %}Symfony is great{% endtrans %}
 
{{ 'Symfony is great'|trans }}
 
{{ 'Symfony is great'|transchoice(1) }}
 
{% transchoice 1 %}Symfony is great{% endtranschoice %}

它也能发现在PHP模板中使用的以下translator用法:

1
2
3
$view['translator']->trans("Symfony is great");
 
$view['translator']->transChoice('Symfony is great', 1);

提取器不能探测到模板之外的翻译信息,也就是说,在表单label或是控制器中的translator用法,将不会被探测到。模板中涉及变量或表达式的动态翻译也不会被探测到,即,下例的情形将不被分析:

1
2
{% set message = 'Symfony is great' %}
{{ message|trans }}

假设你程序的 default_locale 是 fr 并且你配置了 en 作为 fallback locale (见 ConfigurationFallback Translation Locales 以了解如何配置它们)。同时假设你已经在AcmeDemoBundle中设置好了一些 fr locale的 翻译源(译注:即message catalog):

1
2
3
4
5
6
7
8
9
10
11
12
<!-- src/Acme/AcmeDemoBundle/Resources/translations/messages.fr.xliff -->
<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
    <file source-language="en" datatype="plaintext" original="file.ext">
        <body>
            <trans-unit id="1">
                <source>Symfony is great</source>
                <target>J'aime Symfony</target>
            </trans-unit>
        </body>
    </file>
</xliff>
1
2
# src/Acme/AcmeDemoBundle/Resources/translations/messages.fr.yml
Symfony is great: J'aime Symfony
1
2
3
4
// src/Acme/AcmeDemoBundle/Resources/translations/messages.fr.php
return array(
    'Symfony is great' => 'J\'aime Symfony',
);

另外也准备了 en locale 的信息目录:

1
2
3
4
5
6
7
8
9
10
11
12
<!-- src/Acme/AcmeDemoBundle/Resources/translations/messages.en.xliff -->
<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
    <file source-language="en" datatype="plaintext" original="file.ext">
        <body>
            <trans-unit id="1">
                <source>Symfony is great</source>
                <target>Symfony is great</target>
            </trans-unit>
        </body>
    </file>
</xliff>
1
2
# src/Acme/AcmeDemoBundle/Resources/translations/messages.en.yml
Symfony is great: Symfony is great
1
2
3
4
// src/Acme/AcmeDemoBundle/Resources/translations/messages.en.php
return array(
    'Symfony is great' => 'Symfony is great',
);

若要侦测出AcmeDemoBundle的 fr locale中的全部翻译信息,运行:

1
$  php bin/console debug:translation fr AcmeDemoBundle

你会得到如下输出:

它为你显示一个结果表格,当翻译的信息存在于 fr locale时,如果用到了fallback locale en 也会显示在结果中。在此基础上,它还会告诉你翻译内容和回滚中的翻译内容是相同的(这就提示出该条待译信息可能并没有被正确翻译)。进一步地,它会提示 Symfony is great 尚未使用,因为虽然你(在目录)中翻译了它,但并没有在任何地方使用(这个翻译内容)。

现在,如果你在某个模板中翻译该条信息,你会得到如下输出:

state(状态)一栏是空的,表示信息已被翻译为 fr locale并且在一或多个模板中使用了。

如果你从 fr locale的翻译源文件中删除掉 Symfony is great,然后运行此命令,你会得到:

状态显示为信息丢失,因为它没有在 fr locale 中被翻译,但却仍然在模板中使用了。更提示出,在 fr locale中的信息等同于 en locale中的。本例比较特殊,因为未译信息之id等于它在 en locale中的翻译(内容)。

如果你把 en locale下的翻译源文件里的内容拷贝到 fr locale的翻译文件中,并运行此命令,你会得到:

你会看到在 enfr locale中,待译信息的翻译内容是相等的,表明该条信息(的翻译内容)可能是从英语拷到法语而你可能忘了翻译它。

默认时所有的域都会被侦测,但也可以指定一个单一的域:

1
$  php bin/console debug:translation en AcmeDemoBundle --domain=messages

当一个bundle有很多条翻译信息时,只显示尚未使用的或丢失的信息就很有用了,此时使用 --only-unused--only-missing 即可切换:

1
2
$  php bin/console debug:translation en AcmeDemoBundle --only-unused
$  php bin/console debug:translation en AcmeDemoBundle --only-missing

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)