如何在Symfony和Twig中基于参数设置默认翻译域?
首先,咱们先搞定你遇到的几个核心问题:Twig三元表达式报错、翻译提取只识别一个域,以及实现全局动态翻译域的需求,完全不用Git多分支。
一、先修复Twig动态翻译域的语法错误
你之前的三元表达式写法不符合Twig的语法规范,trans_default_domain标签需要接收明确的变量或字符串,正确写法是先把计算后的域赋值给变量,再传入标签:
{% set translation_domain = foobar == 'bar' ? 'messages_bar' : 'messages_foo' %} {% trans_default_domain translation_domain %}
这样就不会触发Attribute "value" does not exist的错误了。不过这种方式仍存在翻译提取的局限性(静态分析工具不会执行Twig逻辑),更推荐下面的全局配置方案。
二、全局动态设置默认翻译域(最优方案)
Symfony完全支持通过配置或事件来全局设置默认翻译域,不用在每个模板里写条件判断。
方法1:直接用参数绑定配置(最简单)
在app/config/config.yml的framework.translator配置段里,直接用你的page参数拼接默认翻译域:
framework: translator: default_path: '%kernel.project_dir%/translations' # 用parameters.yml里的page参数动态设置默认域 default_domain: 'messages_%page%'
容器编译时会自动把%page%替换成你配置的foo或bar,全局默认翻译域就变成了messages_foo或messages_bar,模板里直接用{% trans %}即可,不用额外指定域。
方法2:事件监听器动态设置(适配复杂逻辑)
如果以后需要根据请求参数、用户角色等更复杂条件切换翻译域,可以用kernel.request事件监听器:
- 创建监听器类:
// src/AppBundle/EventListener/TranslationDomainListener.php namespace AppBundle\EventListener; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\Translation\TranslatorInterface; class TranslationDomainListener { private $translator; private $page; public function __construct(TranslatorInterface $translator, string $page) { $this->translator = $translator; $this->page = $page; } public function onKernelRequest(RequestEvent $event) { // 根据page参数设置全局默认翻译域 $this->translator->setDefaultDomain('messages_' . $this->page); } }
- 在
app/config/services.yml中注册监听器:
services: AppBundle\EventListener\TranslationDomainListener: arguments: $translator: '@translator' $page: '%page%' tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
三、解决翻译提取的问题
翻译提取命令是静态分析模板,不会识别动态逻辑,所以需要分别针对两个域执行提取命令:
提取messages_foo的翻译:
php bin/console translation:extract en --config=user --enable-extractor=jms_i18n_routing --output-format=xliff --domain=messages_foo
提取messages_bar的翻译:
php bin/console translation:extract en --config=user --enable-extractor=jms_i18n_routing --output-format=xliff --domain=messages_bar
这样就能分别生成两个域的xliff文件,部署到对应服务器时,默认域会自动绑定page参数,加载对应的翻译文件。
四、验证效果
- 确认
parameters.yml里的page参数配置正确; - 清除缓存:
php bin/console cache:clear; - 在模板里通过
{{ dump(translator.defaultDomain) }}(需将translator注入Twig全局)验证默认域是否正确; - 测试翻译内容是否正常加载。
这种方案完全保持单一代码库,不用分支,通过参数控制翻译域,完美匹配你的需求。
内容的提问来源于stack exchange,提问作者wawa

