首页 > 解决方案 > 为什么约束消息的自动翻译在 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. ”。

然而,以下作品

到目前为止我已经尝试过但没有帮助

有趣的事实:使用 symfony 框架测试类似的设置是成功的。然而不幸的是,该框架对我来说是没有选择的。

谢谢阅读!非常感谢任何有用的评论。:)

标签: phptwigtranslationsymfony4symfony-forms

解决方案


[...]我担心这是一个简单的配置问题,但我不知道我还能尝试什么来使翻译工作。[…]

一个假设,而不是偏离标记一毫米!:-)

当然,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的源代码。


推荐阅读