php - 为什么约束消息的自动翻译在 twig/symfony 中失败?
问题描述
首先:我是 Symfony4 和 Twig 的新手。然而,我希望就我的问题而言,我已经阅读了文档。:)
介绍
好的,我的目标是将 Symfony Form 组件与其他合适的 Symfony 组件集成到现有的 PHP 应用程序中。我创建的表单还依赖于 Translation、Validator 和 Twig-Bridge 组件。我已经按照官方文档中的建议设置了代码。除了约束消息的翻译外,一切都按预期工作,尽管表单标签被正确翻译。
细节
翻译器是用语言环境实例化的'de'
。后备语言环境设置为['de']
. 首先加载来自表单和验证器组件的德语默认翻译 (xlf),然后是我的自定义翻译 (yaml),并在需要时覆盖前者。我设置了两个翻译域:消息和验证器。
我已检查目录是否包含所有德语默认消息,包括约束翻译。这意味着翻译文件已正确加载。在控制器或 Twig 模板中手动翻译约束消息可以正常工作。但是模板中的自动翻译失败了。
我担心这是一个简单的配置问题,但我不知道我还能尝试什么来使翻译工作。在 Twig 模板中单独构建每个表单字段对我来说似乎没有选择。
由于没有翻译缓存,缓存不会成为问题。
(validators.de.yaml)
// creating the custom constraint message
entity.name.not_blank: 'Bitte einen Namen eingeben!'
(控制器.php)
// creating the translator
$translator = new Translator('de');
$translator->setFallbackLocales(['de']);
$translator->addLoader('xlf', new XliffFileLoader());
$translator->addLoader('yml', new YamlFileLoader());
// adding default translations
$translator->addResource('xlf', "path/to/vendor/symfony/form/Resources/translations/validators.de.xlf", 'de', 'validators');
$translator->addResource('xlf', "path/to/validator/Resources/translations/validators.de.xlf", 'de', 'validators');
// adding custom translations
$translator->addResource('yml', "path/to/messages.de.yaml", 'de');
$translator->addResource('yml', "path/to/validators.de.yaml", 'de', 'validators');
…
// setting up Twig
$defaultFormTheme = 'bootstrap_4_layout.html.twig';
$appVariableReflection = new \ReflectionClass('\Symfony\Bridge\Twig\AppVariable');
$twig = new Environment(new FilesystemLoader(['/path/to/views', '/path/to/Resources/views/Form']));
$formEngine = new TwigRendererEngine([$defaultFormTheme], $twig);
$twig->addRuntimeLoader(
new FactoryRuntimeLoader([
FormRenderer::class => function () use($formEngine, $csrfManager) {
return new FormRenderer($formEngine, $csrfManager);
}
])
);
$twig->addExtension(new FormExtension());
$twig->addExtension(new TranslationExtension($translator));
…
// creating the form factory adding the Validator extension
$validator = Validation::createValidator();
$formFactory = Forms::createFormFactoryBuilder()
->addExtension(new ValidatorExtension($validator))
->getFormFactory();
…
// rendering the form using Twig
echo $this->getTwig()->render('form.html.twig', [
'form' => $form->createView()
]);
(实体.php)
// setting up the EntityType form
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('name', TextType::class, [
'constraints' => [
new NotBlank(['message' => 'entity.name.not_blank'])
]
]);
}
测试和结果
约束消息应转换为“ Bitte einen Namen eingeben! ”,而不是显示消息键“ entity.name.not_blank ”。在约束上设置 no message key 会导致“ This value should not be blank. ”而不是“ Dieser Wert sollte nicht leer sein. ”。
然而,以下作品:
{% trans from 'validators' %}entity.name.not_blank{% endtrans %}
使用或{% trans from 'validators' %}This value should not be blank.{% endtrans %}
分别手动翻译消息密钥- 翻译约束消息之前的错误标记(“错误”正确替换为“FEHLER”)
- 翻译表格标签
到目前为止我已经尝试过但没有帮助:
{{ form_widget(form, {'translation_domain': 'validators'}) }}
{% trans_default_domain 'validators' %}
$session->set('_locale', 'de')
$this->getRequest()->setLocale('de')
有趣的事实:使用 symfony 框架测试类似的设置是成功的。然而不幸的是,该框架对我来说是没有选择的。
谢谢阅读!非常感谢任何有用的评论。:)
解决方案
[...]我担心这是一个简单的配置问题,但我不知道我还能尝试什么来使翻译工作。[…]
一个假设,而不是偏离标记一毫米!:-)
当然,ValidatorExtension无法知道Translator(以及因此丢失的翻译消息),除非前者被注入到Validator中,如下所示:
$validatorBuilder = Validation::createValidatorBuilder();
// the essential part: coupling the ValidatorBuilder with the Translator
$validatorBuilder->setTranslator($translator);
$validatorBuilder->setTranslationDomain('validators');
$validator = $validatorBuilder->getValidator();
$formFactory = Forms::createFormFactoryBuilder()
->addExtension(new ValidatorExtension($validator))
->getFormFactory();
不幸的是,文档对找到解决方案没有多大帮助。让我更接近的是加载资源:使用多个加载器,并最终阅读了ValidatorBuilderInterface的源代码。
推荐阅读
- xcode - XCode & SPM - 动态解决包依赖
- .net - 在 Alpine docker 镜像中使用 Kafka 和 GCP SDK 运行服务
- puppet - 使用 Puppet 创建目录并递归复制具有不同访问权限的文件
- wildfly - WildFly - 活动会话列表
- sql - 在rails中按关联值排序数据的最佳方法
- php - 用php在表中丢失数据
- flutter - 尝试...抓住停止应用程序 (Dart/Flutter)
- html - 网络抓取:网络抓取的对象与网站上的信息不匹配,导致 RStudio 崩溃
- python - 大熊猫python中基于组的第n个十分位数的假人
- .net-core - 在 azure functions 3 中,我可以将日志过滤到不同级别的应用程序洞察和控制台