Form label translation in Symfony 2

If you’ve ever used FOS user bundle, they handle all the translation for you for the form’s field labels. Whenever a translation is not there, you see the field’s id instead of seeing any label based on the field’s name like this is usually the case.

This seemed pretty cool to me and I couldn’t help but keep thinking “I want that too”. The reason is that my translations are based on “keys” instead of the actual text. So if my label reads “Contact person’s email”, I’d have to have a key with this name. But when I change this label in English to “Contact’s email” then I would have to change all the keys in the translation files. Which … I don’t want to!

So after a little experimentation, here’s what you can do to use this simple key based ways of translating form labels:

Simple solution

The first very simple solution is to manually set the label for any form field to be that field’s id. It’s super simple and fast to do:

So for each form label you manually specify that the label is the field’s id. Then in your translation file you add the corresponding keys and translations:

And … you’re good to go!

But if you’re as lazy as you should, you do not want to manually do this all the time. So (because you’re lazy), you spend 2 hours wondering “How the hell do they do this in FOSUserBundle so that it’s automatic???” Here’s how:

Generic solution

Form theming!

Form and form fragments can be themed as explained in symfony’s documentation. So we’re gonna use almost the same trick as in FOSUserBundle to translate our own forms.

Field label fragment

First we define a field label fragment. This is a view that you can put for example in “MyBundle:Form:label.html.twig” and that will look like this:

Then you either add this form theme in each page where you have a form or globally in your config file:

And then again you’ll be all set to add the field’s ids in your messages.<locale>.yml with their translations.

Pushing it further

When you use translations and set them in yml files, a nice feature is that you can “group” them. The translation for “mybundle.myform.myfield” can be made in any of the 2 following ways:

But right now we use the field’s id which is usually in the format of “mybundle_myformtype_mysubform_myfield”. We’re almost there. A small change to the form theme we made earlier and all will be good:

And there you go, you can translate your forms and use the nested yml format.

10 thoughts on “Form label translation in Symfony 2

  1. I’ve been using the same approach. The only tiny problem is with collections, they have id like mybundle_myformtype_mysubform_0_myfield where 0 is the position in the collection. Solved it by not using labels in such cases.

  2. Hi,

    Can you explain where you put the files you’ve created (the YML file which contains the labels) ? In which directory exactly ?
    In the config file, you’re referencing a twig file and then, you create a file which looks more like a yaml file and which contains the labels for each field ??? I don’t understand, if you could be clearer, it would help.
    Thank you.

  3. I got translation using

    {{ form_label(form.field, form.field.vars.label|trans) }}

  4. By default Symfony2 translates all labels in a form automatically ;) even things like ‘empty_value’ in choice fields is automatically translated. So no need to do all this.

  5. With the latest Symfony (2.1) you can simply pass a ‘translation_domain’ parameter to the form builder (or each form field) in your controller when you build the form and specify the translation domain you want used for the form or fields. Then instead of actual label text, you just provide the id of translations for each form field. Symfony will then translate it automatically for you.

Comments are closed.