
symfony 提供了一个强大而灵活的翻译组件,允许开发者将应用程序的文本内容国际化。在 twig 模板中,我们通常使用 trans 过滤器或 {% trans %} 标签来标记需要翻译的文本,并可以方便地引入变量以实现动态内容。
例如,以下 Twig 代码展示了如何在翻译字符串中包含变量:
{# 使用 trans 标签 #}
{% trans with {'%name%': 'Hans'} %}Hello %name%{% endtrans %}
{# 使用 trans 过滤器 #}
{{ 'Hello filter %name%'|trans({'%name%': 'Hans'}) }}在初始阶段,这些代码通常会按预期工作,输出 Hello Hans 和 Hello filter Hans。然而,当开发者运行 php bin/console translation:update 命令来提取和更新翻译文件时,一个常见的陷阱可能会导致变量替换功能失效。
当运行 translation:update 命令(例如 php bin/console translation:update --force en)时,Symfony 会扫描代码中的翻译键,并将其添加到指定的翻译文件中。以 XLIFF 格式为例,生成的翻译文件可能如下所示:
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" target-language="en" datatype="plaintext" original="file.ext">
<header>
<tool tool-id="symfony" tool-name="Symfony"/>
</header>
<body>
<trans-unit id="SzX5ua9" resname="Hello %name%">
<source>Hello %name%</source>
<target>__Hello %name%</target> {# 注意这里 #}
</trans-unit>
<trans-unit id="6l2Ebbm" resname="Hello filter %name%">
<source>Hello filter %name%</source>
<target>__Hello filter %name%</target> {# 注意这里 #}
</trans-unit>
</body>
</file>
</xliff>请注意 <target> 标签中的内容。Symfony 的 translation:update 命令会为这些翻译键生成带有前缀(例如 __)的默认目标文本,以便开发者可以轻松识别并填充实际的翻译。然而,它会直接保留源文本中的占位符语法,即 %name%。
问题在于,Symfony 的翻译组件在处理 XLIFF 文件时,通常会利用 ICU MessageFormat。ICU MessageFormat 是一种强大的消息格式化标准,它要求其占位符使用花括号 {},而非百分号 %。因此,当翻译组件尝试解析 <target>__Hello %name%</target> 时,它无法识别 %name% 为一个有效的 ICU 占位符,从而导致变量无法被正确替换,最终在页面上显示为 __Hello %name% 而不是 __Hello Hans。
要解决这个问题,开发者需要手动编辑翻译文件,将 <target> 标签中的占位符语法从 %name% 更改为 ICU MessageFormat 兼容的 {name}。
以下是修正后的 XLIFF 文件示例:
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" target-language="en" datatype="plaintext" original="file.ext">
<header>
<tool tool-id="symfony" tool-name="Symfony"/>
</header>
<body>
<trans-unit id="SzX5ua9" resname="Hello %name%">
<source>Hello %name%</source>
<target>__Hello {name}</target> {# 修正后的占位符 #}
</trans-unit>
<trans-unit id="6l2Ebbm" resname="Hello filter %name%">
<source>Hello filter %name%</source>
<target>__Hello filter {name}</target> {# 修正后的占位符 #}
</trans-unit>
</body>
</file>
</xliff>关键点: 将 <target> 中的 %name% 修改为 {name}。
完成此修改后,当应用程序加载这些翻译文件时,Symfony 的翻译组件将能够正确识别 {name} 占位符,并将其替换为 Twig 模板中传入的相应变量值。
Twig 模板(保持不变):
{# 使用 trans 标签 #}
{% trans with {'%name%': 'Hans'} %}Hello %name%{% endtrans %}
{# 使用 trans 过滤器 #}
{{ 'Hello filter %name%'|trans({'%name%': 'Hans'}) }}XLIFF 翻译文件 (messages.en.xlf) 修正示例:
<!-- ... 其他 XLIFF 内容 ... -->
<body>
<trans-unit id="SzX5ua9" resname="Hello %name%">
<source>Hello %name%</source>
<target>Hello {name}</target> {# 实际翻译时,请移除前缀并提供正确翻译 #}
</trans-unit>
<trans-unit id="6l2Ebbm" resname="Hello filter %name%">
<source>Hello filter %name%</source>
<target>Hello filter {name}</target> {# 实际翻译时,请移除前缀并提供正确翻译 #}
</trans-unit>
</body>
<!-- ... 其他 XLIFF 内容 ... -->经过上述修正并清空 Symfony 缓存后,页面将正确显示 Hello Hans 和 Hello filter Hans。
通过理解 Twig 占位符与 ICU MessageFormat 占位符之间的差异,并正确地在翻译文件中应用 {name} 语法,开发者可以确保 Symfony 应用程序中的变量翻译功能顺畅无阻。
以上就是Symfony Twig 模板中变量翻译的正确姿势:解决占位符替换失效问题的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号