Reputation: 2722
Translating content in twig templates seems easy and straightforward: I run bin/console translation:update
to populate translation files. The issue is that it seems to ignore forms.
After creating entities, repositories and forms/types, I use {{ form_row(form.field) }}
in twig templates to draw the form elements.
Is there a well-established practice on how to customize and translate form labels, placeholders and errors messages?
Must I use form_label
and form_widget
instead of form_row
to customize labels?
Upvotes: 1
Views: 6440
Reputation: 215
Solution of @Koronos is not bad, but I suggest mine, because in @Koronos solution you have to repeat 'translation_domain' => 'forms' over and over again, on each form input. To get rid of this, here is my solution, in controller or whatever place I init form object (code example of Symfony 6.0.0):
<?php
#[Route('/admin/clients/update/{id}', name: 'client_update')]
public function update(Request $request, int $id): Response
{
$client = $this->clientRepository->find($id);
$form = $this->createForm(ClientFormType::class, $client, ['translation_domain' => 'forms']);
// do other actions here
}
After that, I only need to config label on each form input in form class, describing translation key. This is answer for the year 2023 and for Symfony 6.
Upvotes: 0
Reputation: 61
To translate form errors as explained on documentation https://symfony.com/doc/current/validation/translations.html
You need validators.lang_used.format file with key/value par. Then pass the key over Assert validation upon message key.
On Entity
// src/Entity/Author.php
use Symfony\Component\Validator\Constraints as Assert;
class Author
{
/**
* @Assert\NotBlank(message="author.name.not_blank")
*/
public $name;
}
On form creation
$form = $this->createFormBuilder()
->setMethod('GET')
->add('email', TextType::class, [
'constraints' => [
new NotBlank(['message' => 'error.not_blank']),
],
'label' => 'label.email-domain'
])
->getForm();
To translate Label just pass the keys to 'label', the keys need be prefix with label an live on messages.* file.
Translate plain text on view (key/value are defined on messages.* files)
{{ 'save_button'|trans }}
For examples of translation see https://github.com/symfony/demo look for Entity definition, views file and Form Type
Upvotes: 0
Reputation: 557
You could create for example a file named forms.es.yml
here, you can put you traductions in spanish, and in your forms you can chain it like this:
//LoginType.php
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email',
EmailType::class,
[
'translation_domain' => 'forms', //It's translate the label
'constraints' => [
new Email([
'message' => 'email'
])
]
]
)
->add('password',
RepeatedType::class,
[
'type' => PasswordType::class,
'invalid_message' => 'cliente.password_not_equal',
'first_options' => ['label' => 'cliente.password'],
'second_options' => ['label' => 'cliente.repeat_password'],
'translation_domain' => 'forms', //Here is again
'constraints' => [
new NotBlank([
'message' => 'not_blank'
])
]
]
)
->add('current_uri', HiddenType::class);
}
It works since symfony 2.
Another way is in your twig, only print the widget and translate the label:
//index.html.twig
<label>
{{'form.email'|trans({})}}
{{ form_widget('form.email') }} //It only prints the input tag
</label>
Is an easy way, but is less reusable.
Upvotes: 1