首页 > 解决方案 > Symfony:不断收到有关缺少翻译的通知

问题描述

我正在使用 symfony 3.4.19 并有 2 种语言的翻译:英语和荷兰语。我正在使用这个symfony 指南来翻译验证消息

这是我的 UserDTO 带有断言和消息翻译的部分:

class UserDTO
{
    /**
     * @var string
     *
     * @Assert\NotNull(message="security.registration.firstname.required", groups={"createUser", "updateUser"})
     * @Assert\NotBlank(message="security.registration.firstname.required", groups={"createUser", "updateUser"})
     */
    private $firstname;

    /**
     * @var string
     *
     * @Assert\NotNull(message="security.registration.lastname.required", groups={"createUser", "updateUser"})
     * @Assert\NotBlank(message="security.registration.lastname.required", groups={"createUser", "updateUser"})
     */
    private $lastname;

    /**
     * @var string
     *
     * @Assert\NotNull(message="security.registration.email.required", groups={"createUser", "updateUser"})
     * @Assert\NotBlank(message="security.registration.email.required", groups={"createUser", "updateUser"})
     * @Assert\Email(message="security.registration.email.format", groups={"createUser", "updateUser"})
     */
    private $email;

    /**
     * @var string
     *
     * @Assert\NotNull(message="security.registration.password.required", groups={"createUser", "updateUser"})
     * @Assert\NotBlank(message="security.registration.password.required", groups={"createUser", "updateUser"})
     */
    private $plainPassword;
}

所以我有 2 个翻译文件:security.en.yml

"Username could not be found.": "Wrong email or password!"
"Invalid credentials.": "Wrong email or password!"
security:
    login:
        email: 'Email'
        password: 'Password'
    registration:
        firstname:
            title: 'Firstname'
            required: 'A firstname is required'
        lastname:
            title: 'Lastname'
            required: 'A lastname is required'
        email:
            title: 'Email'
            required: 'An email is required'
            format: 'Wrong email format'
        password:
            title: 'Password'
            required: 'A password is required'

和security.nl.yml:

"Username could not be found.": "Verkeerd email of wachtwoord!"
"Invalid credentials.": "Verkeerd email of wachtwoord!"
security:
    login:
        email: 'Email'
        password: 'Wachtwoord'
    registration:
        firstname:
            title: 'Voornaam'
            required: 'Voornaam is verplicht'
        lastname:
            title: 'Achternaam'
            required: 'Achternaam is verplicht'
        email:
            title: 'Email'
            required: 'Email is verplicht'
            format: 'Verkeerd email formaat'
        password:
            title: 'Wachtwoord'
            required: 'Wachtwoord is verplicht'

另外我不使用 symfony 表单构建器,所以我只提交我在 twig 模板中创建的表单:

{% trans_default_domain 'security' %}

{% extends 'base.html.twig' %}

{% block stylesheets %}
    {{ parent() }}
    <link href="{{ asset('css/project/registration.css') }}" rel="stylesheet"/>
{% endblock %}

{% block javascripts %}
    {{ parent() }}
{% endblock %}

{% block body %}
    {{ include('component/main-navbar.html.twig') }}

    <div>
        <h2>Create new account</h2>

        {% if errors is defined %}
            <div class="alert alert-danger">
                <ul>
                    {% for error in errors %}
                        <li>{{ error|trans }}</li>
                    {% endfor %}
                </ul>
            </div>
        {% endif %}

        <form action="/register" method="post">
            <input type="text" name="firstname" placeholder="{{ 'security.registration.firstname.title'|trans }}">
            <input type="text" name="lastname" placeholder="{{ 'security.registration.lastname.title'|trans }}">
            <input type="text" name="email" placeholder="{{ 'security.registration.email.title'|trans }}">
            <input type="text" name="plainPassword" placeholder="{{ 'security.registration.password.title'|trans }}">
            <button type="submit" class="btn btn-success btn-sm float-right">Login <span class="fa fa-lock"></span>
            </button>
        </form>
    </div>

    {{ include('component/footer.html.twig') }}
{% endblock %}

正如您在模板顶部看到的那样,我明确设置了翻译域,即。'安全'。

在控制器中,我有 2 种方法。第一个只是渲染视图,另一个是提交表单。

public function registrationPageAction(Request $request)
{
    return new Response(
        $this->twigService->render(
            'security/register.html.twig',
            [
                'error' => []
            ]
        ),
        200
    );
}

提交表格:

public function registrationSubmitAction(Request $request)
{
    $submittedFormData = $request->request->all();

    $userDTO = new UserDTO();
    $userDTO->setFirstname($submittedFormData['firstname'])
        ->setLastname($submittedFormData['lastname'])
        ->setEmail($submittedFormData['email'])
        ->setPlainPassword($submittedFormData['plainPassword']);

    $fieldErrors = $this->validator->validate($userDTO, null, ['createUser']);

    $errors = [];
    if (count($fieldErrors) > 0)
    {
        foreach ($fieldErrors as $error)
        {
            $errors[] = $error->getMessage();
        }

        return new Response(
            $this->twigService->render(
                'security/register.html.twig',
                [
                    'errors' => $errors
                ]
            ),
            200
        );
    }
}

目前我没有将提交的数据存储在任何地方,我只是想确保翻译工作正常。

因此,当我转到 /register 时,我会按预期看到带有 TRANSLATED 字段的表单。在调试栏中,没有关于缺少翻译的通知: 在此处输入图像描述

提交表单后,我也得到了带有翻译字段的表单,但这次在调试栏中我也有缺少翻译的通知: 在此处输入图像描述

请注意,所有翻译(字段和消息)都可以正常工作。在 config.yml 中,我将后备语言环境设置为“en”,当前语言环境设置为“nl”。

在此处输入图像描述

缺少翻译: 在此处输入图像描述

我真的不明白为什么我一直看到这些通知。有任何想法吗?

更新:

现在我已经摆脱了 security.en.yml 和 security.nl.yml 并仅为测试目的创建了具有以下内容的 app/Resources/translations/validators.en.yml:

firstname: 'Firstname is needed'
lastname: 'Lastname is needed'
email: 'Email is needed'
emailformat: 'Wrong email format'
password: 'Password is needed'

此外,我修改了 UserDTO 类中的验证消息:

class UserDTO
{
    /**
     * @var string
     *
     * @Assert\NotNull(message="firstname", groups={"createUser", "updateUser"})
     * @Assert\NotBlank(message="firstname", groups={"createUser", "updateUser"})
     */
    private $firstname;

    /**
     * @var string
     *
     * @Assert\NotNull(message="lastname", groups={"createUser", "updateUser"})
     * @Assert\NotBlank(message="lastname", groups={"createUser", "updateUser"})
     */
    private $lastname;

    /**
     * @var string
     *
     * @Assert\NotNull(message="email", groups={"createUser", "updateUser"})
     * @Assert\NotBlank(message="email", groups={"createUser", "updateUser"})
     * @Assert\Email(message="emailformat", groups={"createUser", "updateUser"})
     */
    private $email;

    /**
     * @var string
     *
     * @Assert\NotNull(message="password", groups={"createUser", "updateUser"})
     * @Assert\NotBlank(message="password", groups={"createUser", "updateUser"})
     */
    private $plainPassword;
}

在 register.html.twig 我删除了 {% trans_default_domain 'security' %} 并制作了没有字段翻译的表单:

<form action="/register" method="post">
    <input type="text" name="firstname" placeholder="Firstname">
    <input type="text" name="lastname" placeholder="Lastname">
    <input type="text" name="email" placeholder="Email">
    <input type="text" name="plainPassword" placeholder="Password">
    <button type="submit" class="btn btn-success btn-sm float-right">Login <span class="fa fa-lock"></span>
    </button>
</form>

再次提交表单后,我收到了那些烦人的通知: 在此处输入图像描述

我究竟做错了什么?我只是一步一步地按照官方 symfony 指南 :(

标签: phpsymfonysymfony-3.4

解决方案


这个问题在你上一个截图中有点隐藏。验证约束不会使用模板中的默认翻译域。默认情况下,这些消息是从validators域中提取的。

一个选项可能是将消息密钥复制到验证器域的新文件中,您可以更改验证消息的默认域。据我所知,这是通过覆盖参数来完成的,%validator.translation_domain%例如在您的 services.yaml 或 config.yaml 中:

# app/config/config.yaml

parameters:
    validator.translation_domain: security

framework:
    ...

由于这些确实是验证错误,我认为将这些消息保留在验证器域中并在模板中选择性地使用该域会更有意义:

<input type="text" name="firstname" placeholder="{{ 'security.registration.firstname.title'|trans(domain="validators") }}">

或将占位符和验证消息拆分为单独的翻译域(和文件)。

编辑澄清:首先验证器将翻译您的消息,而不是找到翻译,因此翻译是原始密钥。然后,此“翻译”将传递到您模板中的错误处理中,并与您当前的域一起翻译。所以基本上,您的问题是双重翻译验证消息的某种隐藏尝试。


推荐阅读