boxblinkracer/phpunuhi

一个简单的工具,用于处理翻译文件,包括验证、导出、导入等。


README

Build Status GitHub release (latest by date) GitHub commits since latest release (by date) Packagist Downloads

欢迎来到PHPUnuhi - 一个易于组合的框架,用于验证和管理翻译!

仅限PHP开发者?!绝对不是!这个框架是面向所有需要以结构化方式管理翻译的人。它只使用PHP开发;)

Unuhi?这是夏威夷语中的“翻译”或“翻译”。

我为什么要创建它?只是出于好奇,因为我需要这样的东西 :) 这个框架是免费的,没有任何保证或声明。

它是什么,它不是什么!!

这是一个开发工具。它可以用来改进管道、工作流程和QA过程。它也可以用来快速开始添加语言或新句子。但它不能替代那些以专业方式翻译、具有上下文知识和软件知识的服务或人员。请记住这一点,以避免误解这个框架的目标。

现在你已经知道了这些,让我们开始吧!

1. 基本概念

这是一个帮助你 验证和维护翻译 的框架。

尽管它不依赖于特定平台,但你完全可以与Shopware 6和其他平台完美配合使用。

例如,Shopware 6基于JSON文件的片段。如果你为这个平台开发插件,你可以在PHPUnuhi中构建包含所有个人语言文件(如EN、DE、NL等)的翻译集。PHPUnuhi可以帮助你确保你没有忘记任何翻译,确保你的语言文件结构没有出错,甚至可以帮助你导出和导入或翻译条目。

这个框架的一个优点是采用了解耦的 存储格式交换格式 和 * 翻译服务*。您可以结合任何存储格式(JSON、INI、DB等)与任何交换格式进行导入和导出(CSV、HTML等),或使用提供的任何翻译服务(Google、DeepL、OpenAI)。这使得PHPUnuhi成为一个出色的 可组合翻译框架

主要优点

  • 根据CamelCase、KebabCase等验证翻译的结构、缺失值和一致性。
  • 平台独立且可组合的框架,具有不同的组件。
  • 如CSV和HTML之类的交换格式
  • 具有HTML交换格式的实时WebEdit
  • 使用OpenAI(实验性)、DeepL、Google等自动翻译

没有您的平台或文件格式?请随时贡献 :)

2. 安装

您可以使用Composer使用PHPUnuhi。只需使用此脚本安装即可。

composer require boxblinkracer/phpunuhi

一旦您有了配置,就可以使用此命令运行它。

php vendor/bin/phpunuhi validate

3. 配置

整个配置都使用XML完成。

您可以在配置中创建不同的 翻译集

单个 翻译集 包含一个或多个 地区

地区通常由一个 单个文件 定义,该文件包含该地区实际的 翻译。但根据所使用的存储格式,它也可以在数据库中自动搜索等。

这意味着,单个 翻译集多个地区 组成,这些地区在结构上应该匹配,但翻译值不同。

如何定义这样的翻译集完全取决于您。

让我们创建一个新的 phpunuhi.xml 文件(或将其重命名为其他名称)。

<phpunuhi
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="./vendor/boxblinkracer/phpunuhi/config.xsd"
>
    <translations>

        <set name="Storefront">
            <format>
                <json/>
            </format>
            <locales>
                <locale name="de">./snippets/storefront/de.json</locale>
                <locale name="en">./snippets/storefront/en.json</locale>
            </locales>
        </set>

    </translations>
</phpunuhi>

这是一个简单的配置,但您也可以做更多的事情。看看这个

<phpunuhi
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="./vendor/boxblinkracer/phpunuhi/config.xsd"
>
    <translations>

        <set name="Storefront JSON">
            <format>
                <json indent="4" sort="true"/>
            </format>
            <locales>
                <locale name="de">./snippets/de.json</locale>
                <locale name="en">./snippets/%locale%.json</locale>
            </locales>
        </set>

        <set name="Products">
            <format>
                <shopware6 entity="product"/>
            </format>
            <filter>
                <exclude>
                    <key>meta_*</key>
                </exclude>
            </filter>
            <locales>
                <locale name="de-DE"/>
                <locale name="en-GB"/>
            </locales>
        </set>

    </translations>
</phpunuhi>

每个集合都可以有自己的 存储格式(默认为JSON)。

一些存储格式,如JSON,可以在翻译集中定义单独的属性。

有关附录中存储格式部分的附加属性更多信息,请参阅。

4. 命令

4.1 验证所有命令

通过运行以下命令开始对您的翻译进行全面验证。这验证了所有内容 - 简单且简单。

# loads configuration phpunuhi.xml as default
php vendor/bin/phpunuhi validate:all 

# provide custom configuration
php vendor/bin/phpunuhi validate:all  --configuration=./translations.xml

# generate a junit report in a custom folder
php vendor/bin/phpunuhi validate:all  --report-format=junit --report-output=.reports/junit.xml

# ignore a configured coverage and use strict checks again
php vendor/bin/phpunuhi validate:all --ignore-coverage

4.2 验证乱码命令

什么是混乱?这很简单,就是那些在您的任何地区都没有值的翻译键。这意味着这些键可能甚至没有被您的软件使用,这意味着它们可能可以删除。

要运行混乱检测,请运行此命令

php vendor/bin/phpunuhi validate:mess 

# provide custom configuration
php vendor/bin/phpunuhi validate:mess  --configuration=./translations.xml

# generate a junit report in a custom folder
php vendor/bin/phpunuhi validate:mess  --report-format=junit --report-output=.reports/junit.xml

4.3 验证覆盖率命令

您还可以单独验证您的翻译覆盖率。

开始配置您的XML中的覆盖率,无论是所有翻译集还是每个翻译集。

请参阅附录以配置覆盖率值!

php vendor/bin/phpunuhi validate:coverage 

# provide custom configuration
php vendor/bin/phpunuhi validate:coverage --configuration=./translations.xml

4.4 验证结构命令

这仅验证了您的翻译的结构,而不验证内容或任何规则。

php vendor/bin/phpunuhi validate:structure 

# provide custom configuration
php vendor/bin/phpunuhi validate:structure --configuration=./translations.xml

4.5 修复结构命令

如果您的存储不匹配,您可以使用修复命令轻松确保它们同步。请注意,这将仅创建空翻译,以便结构相同。

最终翻译在最后不是100%有效的...只是存在的!

# Fixes all sets of the configuration
php vendor/bin/phpunuhi fix:structure

# Fixes only a provided set of your configuration
php vendor/bin/phpunuhi fix:structure --set="storefront"

4.6 修复乱码命令

此命令将自动删除在您的任何地区中都没有值的所有翻译键。由 validate:mess 命令检测到的键可能最终不会被使用。因此,此命令将删除它们。

# Fixes all sets of the configuration
php vendor/bin/phpunuhi fix:mess

# Fixes only a provided set of your configuration
php vendor/bin/phpunuhi fix:mess --set="storefront"

4.7 导出命令

您可以将翻译导出为 CSV文件、HTML WebEdit电子表格或其他支持的交换格式。然后,可以将这些文件传递给外部翻译人员或公司。

每一行将包含翻译键,该行中的每一列都将是一个不同的翻译(如果是CSV文件)。

# default export in default exchange format CSV
php vendor/bin/phpunuhi export 

# default export in specific exchange format
php vendor/bin/phpunuhi export ... --format=html

# provide custom export folder
php vendor/bin/phpunuhi export ... --dir=./exports

# only export single set "storefront"
php vendor/bin/phpunuhi export ... --set="storefront"

# only export translation entries that are not yet completely translated in all locales.
php vendor/bin/phpunuhi export ... --empty

有关格式选项和参数的更多信息,请参阅下面的附录!

4.8 导入命令

您可以从CSV文件或其他支持的交换格式导入翻译。这将自动更新分配给导入的翻译集的存储(JSON等)。

建议在批准之前使用版本控制来验证更改。

# import from default format CSV
php vendor/bin/phpunuhi import --set=storefront --file=storefront.csv

# import with other exchange format
php vendor/bin/phpunuhi import ... --format=html

4.9 状态命令

使用此命令获取您翻译的统计信息和报告。这包括覆盖率和找到的单词数量。

php vendor/bin/phpunuhi status 

4.10 翻译命令

PHPUnuhi包含使用外部服务自动为您翻译缺失值的选项。

translate命令将在您的翻译中搜索空值。

如果找到空翻译,它将请求外部服务进行翻译。此请求中将翻译的文本是另一种语言的翻译。

例如,如果您的“英语”翻译为空,PHPUnuhi将找到您的“德语”文本并将其发送到外部服务。然后将英语结果保存到您的存储中。

# translate using GoogleWeb
php vendor/bin/phpunuhi translate --service=googleweb

# translate using DeepL
php vendor/bin/phpunuhi translate --service=deepl --deepl-key=xyz

# translate only the set "storefront"
php vendor/bin/phpunuhi translate ... --set="storefront"

# force the translation of "en". This will translate everything, not only empty values
php vendor/bin/phpunuhi translate ...  --force=en

# define what locale will be used as source for the translation. 
# If not defined, any locale with an existing value will be used.
php vendor/bin/phpunuhi translate ...  --source=en

有关格式选项和参数的更多信息,请参阅下面的附录!

4.11 列出翻译命令

此命令允许您输出Translation-Sets中所有可用的翻译键。使用此命令来调试和分析您的翻译。

php vendor/bin/phpunuhi list:translations 

4.12 迁移命令

还可以将翻译从一种存储迁移到另一种存储。只需使用迁移命令并提供目标存储作为输出格式。

php vendor/bin/phpunuhi migrate --output=json

4.13 扫描使用命令

通常您有使用翻译键的模板文件。扫描命令有助于扫描所有这些文件,并查看您的所有翻译键是否实际在其中使用。

php vendor/bin/phpunuhi scan:usage --dir=./src --scanner=twig

# provide custom configuration
php vendor/bin/phpunuhi scan:usage --dir=./src --scanner=twig --configuration=./translations.xml

# custom set
php vendor/bin/phpunuhi scan:usage --dir=./src --scanner=twig --set=storefront

# verbose mode to show more output, like scanned files and so on
php vendor/bin/phpunuhi scan:usage --dir=./src --scanner=twig --verbose

请注意,这只是一个辅助命令,用于在模板文件中查找未使用的翻译。这里找到的键可能仍在其他地方使用,例如JS文件、PHP文件等!在考虑清楚之前,请不要立即删除它们。

5. 验证过程

PHPUnuhi集成了不同的验证器。这些根据您的配置和使用的命令执行。

当运行validate:all命令时,将运行所有验证器,而其他验证器可能只使用特定的验证过程。

简而言之,这是一份PHPUnuhi可以为您测试的事项清单。

5.1 结构验证

该命令将检查Translation-Set的所有区域设置是否具有相同的结构。如果不一致,您可能遗漏了某些内容;)

5.2 空内容验证

如果在翻译中发现缺失的翻译(空值),验证过程将失败。这有助于防止在您任何区域设置中遗漏某些翻译。

5.3 样式验证

如果您提供了允许的大小写样式列表,验证命令将自动测试所有翻译键是否匹配您提供的样式。

5.4 规则验证

如果您提供了特定规则,如最大嵌套深度等,这些规则也将被测试。

您可以在附录中找到可能的规则。

为什么不全部作为规则?因为随着时间的推移,事情在增长,是的,所有这些都可以成为规则,但仍然,规则的基本思想是它们确实是个人化和可配置的,而其他验证器则更意味着作为“核心”和标准验证步骤。

6. 用例

以下是几个用例和想法,以帮助您开始。

6.1 CI管道中的验证

您想要确保的一件典型的事情是,您的插件/软件没有遗漏任何必需的翻译。

这可以直接在您的CI管道中完成。只需安装您的依赖项并运行验证命令。如果检测到错误,此命令的退出值将自动停止您的管道。

6.2 与外部翻译机构合作

外部翻译机构通常需要CSV导出。您可以轻松生成并导出CSV文件供合作伙伴机构使用。

一旦他们调整了翻译,他们可以将文件发回给您,然后您只需使用导入命令再次导入它。

6.3 使用HTML进行实时WebEdit

如果您有测试或预发布系统,您甚至可以更进一步。只需想象设置一个在部署后运行的cron作业,或作为计划作业。这个cron作业可以触发PHPUnuhi的HTML导出,输出目录是一个在DocRoot中可用的文件夹。然后这个HTML文件可能通过类似这样的方式暴露出来 https://stage.my-shop.com/snippets

任何想要查看所有翻译或甚至修改它们的人都可以轻松地在他们的浏览器中完成。由于您使用cronjob生成HTML,它总是自动更新。

6.4 使用Google、DeepL等自动翻译

您可以通过使用外部服务自动翻译缺失的(或所有)翻译。这可以是GoogleWeb、GoogleCloud甚至是DeepL。提供您的API密钥(如果服务需要)并见证魔法的发生。

在版本控制中进行双重检查和批准仍然是一个不错的选择。

7. 警告

请记住这些事项

  • 翻译服务并不总是正确的!请始终验证自动翻译的文本。
  • 如果您使用的是直接连接到数据库的存储格式,确保在导入翻译之前创建备份!

8. 附录

8.1 导入

您可以将其他配置文件导入到主配置中。如果您想将配置分割成多个文件和包,这将很有用。

<phpunuhi>
    <imports>
        <import resource="./folder/sub_config.xml"/>
    </imports>

    <translations>
        ...
    </translations>
</phpunuhi>

8.2 区域设置

每个翻译集都包含多个区域设置。每个区域设置通过一个名称和一个文件名或数据库表(取决于格式类型)来定义。目的是,翻译集中的每个区域设置都应在这些语言中匹配(例如,所有文件都应该具有相同的结构)。

您还可以使用属性base="true"指定基本区域设置。这将在需要知道包含所有值的基区域设置的某些功能中使用。例如,如果定义了基本区域设置并且没有在命令中指定其他源,翻译服务将优先使用基本区域设置作为翻译源。

这就是定义区域设置的方式(在这个示例中包含文件)。您还可以使用占位符%locale%%locale_lc%%locale_uc%%locale_un%来简化操作。这将重用区域设置名称在文件名中。 locale_lc是小写,locale_uc是大写。%locale_un%-更改为_下划线。(fr-CH到fr_CH)

如果您所有文件都在同一基本目录中,您还可以为basePath提供一个占位符,并为此使用文件目录。

<set name="sample">
    <locales basePath="./Bundles/MySuperBundle/Resources/snippets/%locale_un%">
        <!-- Bundles/MySuperBundle/Resources/snippets/DE/storefront-de.json -->
        <locale name="DE" base="true">%base_path%/storefront-%locale_lc%.json</locale>

        <!-- Bundles/MySuperBundle/Resources/snippets/en/storefront-EN.json -->
        <locale name="en">%base_path%/storefront-%locale_uc%.json</locale>

        <!-- Bundles/MySuperBundle/Resources/snippets/fr_CH/storefront-fr-CH.json -->
        <locale name="fr-CH">%base_path%/storefront-%locale%.json</locale>
    </locales>
</set>

8.3 存储格式

存储格式定义了您的翻译如何存储。每种格式都有自己的加载和保存实现。

8.3.1 格式

以下格式目前受支持。

8.3.1.1 JSON

JSON格式表示您的文件存储在单独的JSON文件中。每个区域设置都有自己的JSON文件。一个集合中所有文件的JSON结构应该匹配。

<set name="sample">
    <format>
        <json indent="4" sort="true"/>
    </format>
    <locales>
        <locale name="de">./snippets/de.json</locale>
        <locale name="en">./snippets/en.json</locale>
    </locales>
</set>
8.3.1.2 INI

INI格式表示您的文件存储在单独的INI文件中。每个区域设置都有自己的INI文件。一个集合中所有文件的INI结构应该匹配。

也可以将所有翻译存储在一个INI文件中。为此,您可能想要使用iniSection功能,并将相同的INI文件分配给所有区域设置,但具有不同的部分。

<set name="sample">
    <format>
        <ini sort="true"/>
    </format>
    <locales>
        <locale name="de">./snippets/de.ini</locale>
        <locale name="en">./snippets/en.ini</locale>
    </locales>
</set>

<set name="sample">
<format>
    <ini sort="true"/>
</format>
<locales>
    <locale name="de" iniSection="de-DE">./snippets/snippets.ini</locale>
    <locale name="en" iniSection="en-GB">./snippets/snippets.ini</locale>
</locales>
</set>
8.3.1.3 PO

一些平台基于PO文件进行翻译。

这种存储类型确保读取和写入PO文件。目前它只覆盖了msgidmsgstr字段。

<set name="sample">
    <format>
        <po/>
    </format>
    <locales>
        <locale name="de">./snippets/de.php</locale>
        <locale name="en">./snippets/en.php</locale>
    </locales>
</set>
8.3.1.4 PHP

一些平台基于PHP数组进行翻译。这意味着这些文件构建一个翻译的键值数组,然后简单地返回。

消费服务可以简单地“require”该文件,因此加载翻译数组。

这种存储类型确保读取和写入返回单个数组对象的PHP文件。

<set name="sample">
    <format>
        <php sort="true"/>
    </format>
    <locales>
        <locale name="de">./snippets/de.php</locale>
        <locale name="en">./snippets/en.php</locale>
    </locales>
</set>
8.3.1.5 Shopware 6

Shopware 6格式允许您直接在数据库和Shopware实体上使用PHPUnuhi。

我们所说的实体是什么?这些是在数据库中存储的平台真实对象。这意味着snippetsproductssalutationsshipping methods等。基本上,数据库中具有_translation表的所有内容。

只需运行status命令,查看您商店中所有产品的翻译覆盖率。不错,不是吗?或者让DeepL自动翻译您的数据?!

要访问 Shopware 的数据库,您可以通过确保连接的 ENV 变量正确设置,或者提供自定义凭据来在配置 XML 的 php 部分。

请注意,在数据库中,片段的处理方式不同。为了使您的生活更轻松,我们已添加了一个名为 snippet 的虚构实体名称,该名称将自动连接到片段表,而不是实体翻译表。

<phpunuhi>
    <php>
        <env name="DB_HOST" value="128.0.0.1"/>
        <env name="DB_PORT" value="3306"/>
        <env name="DB_USER" value=""/>
        <env name="DB_PASSWD" value=""/>
        <env name="DB_DBNAME" value="shopware"/>
    </php>

    <translations>

        <set name="Products">
            <format>
                <shopware6 entity="product"/>
            </format>
            <locales>
                <locale name="de-DE"/>
                <locale name="en-GB"/>
            </locales>
        </set>

        <set name="categories">
            <format>
                <shopware6 entity="category"/>
            </format>
            <locales>
                <locale name="en-GB"/>
                <locale name="de-DE"/>
            </locales>
            <filter>
                <include>
                    <key>name</key>
                </include>
            </filter>
        </set>

        <set name="Snippets">
            <format>
                <shopware6 entity="snippet"/>
            </format>
            <locales>
                <locale name="de-DE"/>
                <locale name="en-GB"/>
            </locales>
        </set>

        <set name="State Machine States">
            <format>
                <shopware6 entity="state_machine_state"/>
            </format>
            <locales>
                <locale name="de-DE"/>
                <locale name="en-GB"/>
            </locales>
        </set>

    </translations>
</phpunuhi>
8.3.1.6 YAML

YAML 格式意味着您的文件存储在单独的 YAML 文件中。每个区域都有其自己的 YAML 文件。一套文件中的 YAML 结构应该匹配。

<set name="sample">
    <format>
        <yaml indent="4" sort="true"/>
    </format>
    <locales>
        <locale name="de">./snippets/de.yaml</locale>
        <locale name="en">./snippets/en.yaml</locale>
    </locales>
</set>

8.3.2 自定义格式

您还可以注册自定义存储。创建一个类,并根据您的需求实现 StorageInterface

然后只需使用此函数注册您的存储。

StorageFactory::getInstance()->registerStorage($myStorage);

最简单的方法是使用 bootstrap 文件,并在您的 XML 配置中指定它来加载自定义存储。

<phpunuhi
        bootstrap="./autoload.php">
</phpunuhi>

8.4 过滤器

您可以使用过滤器来修改受保护翻译键的列表。

您可以使用 includeexclude 列表。包含意味着,只有这些字段将被加载,而排除意味着,除了这些字段之外的所有内容。组合是不可能的。

您还可以使用 * 字符来使用 占位符

<set>
    <filter>
        <include>
            <key>name</key>
        </include>
        <exclude>
            <key>custom_fields</key>
            <key>meta_*</key>
        </exclude>
    </filter>
</set>

8.5 组

某些存储格式会自动将翻译捆绑成组。这意味着,更多的翻译属于一个“东西”。这个“东西”取决于存储格式的类型。

例如,在 Shopware 6 中,一个组是一个“实体”。所以对于“产品”上的翻译集,1 个组代表一个特定的产品,并为不同的产品属性有多个翻译。

如果检测到组,交换格式应该正确处理这些内容。CSV 格式有一个单独的列用于组,导入也应正确工作。

另一方面,HTML 格式在表中显示匹配的样式,这样您就知道所有翻译都属于这个组。

8.6 样式

为了保持所有翻译键的一致性,您可以为允许的样式设置一个列表。validate 命令将自动测试,您的所有翻译键是否至少匹配提供的一种样式。

如果没有提供样式,则跳过样式测试。

以下是一些可能的样式

  • camel
  • pascal
  • kebab
  • lower
  • upper
  • snake
  • start
  • number
  • none

请注意,none 可以用于显式禁用特定级别的样式检查,而其他级别可能针对配置的样式进行验证。这对于具有旧键的旧结构很有用。

<set>
    <styles>
        <style>pascal</style>
        <style>kebab</style>
    </styles>
</set>

除了全局样式外,如果您有如 JSON 或 PHP 之类的嵌套存储,还可以在 特定级别 上设置特定样式。

您甚至可以将它与没有级别的样式混合。在这种情况下,没有级别的样式将在没有为其级别指定特定样式的每个级别上全局检查。

以下示例对于此键将是“有效”的:global.businessEvents.mollie_checkout_order_success。只有级别 1 的驼峰式将被检查,而不会检查级别 0 和 2。

<set>
    <styles>
        <style level="0">snake</style>
        <style level="2">snake</style>
        <style>camel</style>
    </styles>
</set>

有时您在一个平台中工作,其中存在一些键名,它们只需要这样,即使您的指南是其他东西。在这种情况下,您可以向 ignore list 添加这些键。被忽略的键将不会用于样式验证。

您可以使用属性 fqp(完全合格路径)来告诉验证器您是否提供了具有完整嵌套级别的键。如果设置为 TRUE,则验证过程将使用精确匹配,包括键的完整嵌套级别(root.sub.MY_WEIRD_KEY)。如果设置为 FALSE,则无论其嵌套级别如何,都会搜索键名。如果没有提供 fqp 属性,则默认值为 TRUE。

<set>
    <styles>
        <style>snake</style>
        <ignore>
            <key>root.sub.MY_WEIRD_KEY</key>
            <key fqp="true">root.sub.MY_WEIRD_KEY</key>
            <key fqp="false">MY_WEIRD_KEY</key>
        </ignore>
    </styles>
</set>

8.7 规则

您可以添加额外的规则来扩展翻译集的验证。请查看以下列表中所有支持的规则。

<set>
    <rules>
        <duplicateContent>false</duplicateContent>
        <nestingDepth>3</nestingDepth>
        ...
    </rules>
</set>

8.8.1 嵌套深度

嵌套深度规则允许您在嵌套存储类型达到最大深度时抛出错误。这有助于您控制深度。

<nestingDepth>3</nestingDepth>

8.8.2 键长度

键长度规则允许您在键达到最大长度时抛出错误。

<keyLength>20</keyLength>

8.8.3 不允许的文本

提供一份文本列表,这些文本不得出现在您的任何翻译中。您可以用于任何您想要的内容,如脏话、政治不正确的短语等。

<disallowedTexts>
    <text>wordA</text>
    <text>wordB-phrase</text>
</disallowedTexts>

8.8.4 重复内容

有时您想要通过避免在同一区域中重复值来保持翻译的简洁和精简。想象一下简单的翻译值“保存”在单个区域中多次出现?这不是在文件中只保留一个翻译条目更好吗?

在这种情况下,您可以使用此规则。一旦设置为false,验证器将自动警告您,如果您在单个区域中配置了多个翻译值。

您需要为每个区域配置此规则。如果您想配置所有区域(或所有未明确配置的区域),您可以使用通配符来表示其余部分。

<duplicateContent>
    <locale name="de">false</locale>
    <locale name="*">true</locale>
</duplicateContent>

8.8.5 空内容

有时有必要指定可以有空翻译值。也许因为社交媒体链接在所有区域中都没有区别,并且可能甚至不需要翻译。

对于此特定用例,有提供“允许列表”的选项,这些键可以保持为空。

如果您想在所有语言中都允许它为空,请使用通配符区域或甚至跳过区域。

<emptyContent>
    <key name="social_media.youtube.link">
        <locale>*</locale>
    </key>
    <key name="social_media.facebook.link"/>
</emptyContent>

除此之外,您还可以指定允许为空的区域。

<emptyContent>
    <key name="social_media.youtube.link">
        <locale>DE</locale>
        <locale>IT</locale>
        <locale>FR</locale>
    </key>
</emptyContent>

如果满足基于此规则的空翻译条件,您的验证将始终通过。

8.8 PHP环境变量

XML配置允许您创建自定义的ENV变量。根据您在PHPUnuhi中使用的组件,一些组件需要特定的ENV变量,例如Shopware 6数据库连接。这些可以通过在您的服务器上导出ENV变量或在XML配置中简单地提供它们来设置。

<phpunuhi>
    <php>
        <env name="DB_HOST" value="128.0.0.1"/>
        <env name="DB_PORT" value="3306"/>
        <env name="DB_USER" value=""/>
        <env name="DB_PASSWD" value=""/>
        <env name="DB_DBNAME" value="shopware"/>
    </php>
</phpunuhi>

8.9 交换格式

交换格式定义了如何导出和导入翻译数据。主要目的是将其发送给翻译公司或其他人,并能够再次将其导入到您的系统中。

以下格式目前受支持。

8.9.1 CSV

  • 格式:"csv"

CSV格式是一个众所周知且稳定的互操作性格式。您可以使用Microsoft Excel、Apple Numbers以及简单的文本编辑器等打开CSV文件。唯一的缺点是,Excel和Numbers可能会强制您以它们的格式保存更新的文件(只需注意这一点即可)。

好处是您可以简单地在电子表格中打开所有翻译。每个翻译键都有自己的行,而在该行中,所有区域值都有自己的列。

8.9.2 HTML / WebEdit

  • 格式:"html"

HTML导出可以帮助您将所有翻译导出到单个HTML文件中。然后您可以在浏览器中打开此文件并立即开始编辑您的翻译。

完成编辑后,只需单击“保存翻译”。这将下载一个名为html.txt的文件,您可以用PHPUnuhi中的格式html将其再次导入到系统中。

8.9.3 JSON

  • 格式:"json"

JSON格式是一个简单的JSON文件,其中包含所有翻译键及其值的列表。

{
  "id": "group--state_machine_018f6237aded716a9d5d74d49254115d.name",
  "group": "state_machine_018f6237aded716a9d5d74d49254115d",
  "key": "name",
  "en-GB": "Refund state",
  "de-DE": "Erstattungsstatus"
}

8.9.4 自定义交换格式

您还可以注册自定义交换格式。创建一个类并根据您的需求实现ExchangeInterface

然后只需使用此函数注册您的交换格式

ExchangeFactory:: getInstance()->registerExchangeFormat($myFormat);

最简单的方法是使用 bootstrap 文件,并在您的 XML 配置中指定它来加载自定义存储。

<phpunuhi
        bootstrap="./autoload.php">
</phpunuhi>

8.10 翻译服务

翻译器是支持(外部)服务,可以自动为您翻译空值。这些服务通常需要一个API密钥,需要为PHPUnuhi提供。

8.10.1 DeepL

  • 服务:"deepl"

DeepL是领先的翻译服务之一。如果您有DeepL的API密钥,您可以直接将翻译请求发送到他们的API。

DeepL 允许您将文本翻译成正式或非正式的语言。这项功能仅适用于某些目标语言,例如“德语”(“du”与“Sie”)。您只需在翻译命令中应用参数“--deepl-formal”即可请求正式语言。

8.10.2 Google Cloud Translate

  • 服务:“googlecloud”

Google Cloud Translation 允许您使用 Google 的 AI 服务。如果您有 API 密钥,可以在运行翻译命令时轻松提供它。

8.10.3 Google Web Translate

  • 服务:“googleweb”

此服务仅消耗 Google 网页。因此,它与您访问 Google 搜索页面的操作相同。由于这个原因,大量请求可能会导致您的 IP 地址暂时被封锁。

这主要是为了教育目的。尽管它可行,但您应该考虑获取真实的 Google API 密钥以用于其服务的商业和严肃用途。

8.10.4 OpenAI GPT Translate

  • 服务:“openai”

这种类型的翻译器使用最新的 OpenAI 技术来翻译您的文本。让 AI 帮助您翻译文本。

要使用它,您需要在 www.openai.com 创建 API 密钥并将其作为参数提供。就这样!

这确实是在最后一分钟添加的,但它工作得相当不错。如果您有任何调整,请随时贡献:)

8.10.5 自定义翻译器

您还可以注册自定义翻译器。创建一个类,并根据您的需求实现 TranslatorInterface

然后只需使用此函数简单地注册您的翻译器

TranslatorFactory::getInstance()->registerTranslator($myTranslator);

最简单的方法是使用 bootstrap 文件,并在您的 XML 配置中指定它来加载自定义存储。

<phpunuhi
        bootstrap="./autoload.php">
</phpunuhi>

8.11 验证报告

运行 验证 命令后,可以生成报告。这有助于您在不同系统和平台中使用结果。

验证命令有两个参数 --report-format=xyz--report-output=abc,用于提供特定的格式和自定义输出文件名。根据验证结果使用此功能生成报告。

8.11.1 JUnit报告

在启动验证时提供以下参数可以生成 JUnit XML 报告。

  • 报告格式:“junit”

8.11.2 JSON报告

在启动验证时提供以下参数可以生成 JSON 报告。

  • 报告格式:“json”

8.12 保护

PHPUnuhi 允许您配置标记或甚至完整的术语,并保护它们不被翻译。为什么您需要这样做呢?!

某些存储格式(或甚至用例)可能包含文本值内的占位符。这通常有助于软件用真实值替换这样的占位符。以下是一个示例

"lblGreeting": "Hi, welcome {firstname}"

文本中包含占位符 {firstname},但软件使用这个静态密钥,并用客户的真实姓名替换它。这意味着,这个占位符不应该由翻译服务翻译!

保护功能允许您将一个 标记 列表添加到您的翻译集中。标记由这样的占位符的 开始结束 文本组成。

您还可以配置必须不被翻译的完整 术语。如果您有品牌名称或任何不应该意外翻译的单词,这将非常完美。

<set>
    ...
    <protect>
        <marker start="{" end="}"/>
        <marker start="%" end="%"/>
        <marker start="{%" end="%}"/>
        <term>Shopware</term>
        <term>iPhone</term>
    </protect>
</set>

8.13 覆盖率

您还可以配置翻译的覆盖率。

这意味着您可以为单个 TranslationSet 中的所有区域定义特定的覆盖率,分别或总体,或者甚至可以定义所有翻译集中所有区域的特定区域或总体覆盖率。

开始配置您的XML中的覆盖率,无论是所有翻译集还是每个翻译集。

<coverage minCoverage="20">
</coverage>
<coverage>
    <locale name="de">100</locale>
    <locale name="en">80</locale>
</coverage>

这些 覆盖率 节点可以在 <phpunuhi> 的根级别或每个 <set> 节点内部使用。

以下是一个设置了所有覆盖率选项的示例。请记住,这当然没有意义也不可行。

<phpunuhi>

    <translations>

        <set name="Administration">
            <format>
                <json indent="2" sort="true" eol-last="true"/>
            </format>
            <locales>
                <locale name="en">en.json</locale>
                <locale name="de">de.json</locale>
            </locales>
            <coverage minCoverage="80">
                <locale name="de">80</locale>
                <locale name="en">80</locale>
            </coverage>
        </set>

    </translations>

    <coverage minCoverage="80">
        <locale name="de">80</locale>
        <locale name="en">80</locale>
    </coverage>

</phpunuhi>

请注意,一旦配置了覆盖范围,"验证:所有"命令将不会像以前那样严格执行。严格错误将只视为警告,并且只考虑覆盖结果来决定CLI退出码。然而,您可以通过提供单独的选项来强制再次进行严格验证。

8.14 扫描器

扫描器允许您扫描文件中翻译键的出现。这使得您能够,例如,扫描您的TWIG文件,查看您的所有键是否确实在某处被使用。

以下是目前支持的扫描器列表

  • twig
  • mjml

您还可以注册自定义扫描器。创建一个类并按照您的需求实现ScannerInterface

然后只需使用此函数简单地注册您的翻译器

ScannerFactory::getInstance()->registerScanner($myScanner);