How to localize Symfony2 forms?

I have a Symfony2 form where a user can enter an address that is now in a fixed format, and since we want to offer our software internationally, I'm looking for the best way to implement this in SF.

Instead of creating one common, address typewe would like to localize forms with one common format as a reserve for unsupported locales.

I want to separate layout and localization (order, grouping, labels, translations, required and optional fields) from processing (PHP / SF) forms and actual rendering (TWIG).

I came to this: create a form type addressfrom a database model containing all possible fields. Add this form type to the branch automatically by calling form_widget(form)or, if necessary, individual fields. And finally; Define the "layout" of the form in some configuration format (YML, array, whatever) and extend the default TWIG form rendering to iterate through the form elements defined in the specified configuration.

For example, the address configuration for the Netherlands and the USA will be:

- NL-nl
  - [firstname, infix, lastname]
  - [street1, number]
  - [postcode, city]
- EN-us
  - [fullname]
  - [street1]
  - [street2]
  - [city, state]
  - [zip]

Later we will add localized labels, classes, optional and required fields, etc. to this configuration.

At the moment, our big question is: where to put this config? Use a simple array in a class finishView? Put the configuration in a YML file that is processed by form types that require a localized form layout?

, .

+4
2

, , ..

- , . .

?

-, :

LocaleAddressType "locale", -, Entity , "".

LocaleAddress:

// src/AppBundle/Entity/LocaleAddress.php

use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Table()
 * @ORM\Entity()
 */
class LocaleAddress
{
    /**
     * @var string
     *
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @Assert\NotBlank(groups={"nl-NL", ...})
     * @ORM\Column(type="string", nullable=true)
     */
    private $firstName;

    // ...
}

nullable=true. , NotBlank groups .

# AppBundle/Resources/config/locale_address_form.yml
address_form:
   nl-NL:
      - [firstname, infix, lastname]
      - [street1, number]
      - [postcode, city]
   en-US:
      - [fullname]
      - [street1]
      - [street2]
      - [city, state]
      - [zip]

LocaleAddressType locale, Locale::getDefault()

// src/AppBundle/Form/Type/LocaleAddressType.php

class LocaleAddressType extends AbstractType
{ 
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $config = $this->loadLocaleFormConfig($options['locale']);

        foreach ($config as $fields) {
            foreach (fields as $field) {
                $builder->add($field);
            }
        }
    }

    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars['config'] = $this->loadLocaleFormConfig($options['locale']);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => 'AppBundle\Entity\LocaleAddress',
            'locale', \Locale::getDefault(),
        ]);

        // force that validation groups will equal to configured locale.
        $resolver->setNormalizer('validation_groups', function (Options $options) {
            return [$options['locale']];
        });

        $resolver->setAllowedTypes('locale', ['string']);

        // pending validate the custom locale value.
    }

    private function loadLocaleFormConfig($locale) 
    {
        $config = Yaml::parse(file_get_contents('path/to/locale_address_form.yml'));

        return $config['address_form'][$locale];        
    }
}

.. , locale.

:

# app/config/services.yml
services:
    app.form.locale_address:
        class: AppBundle\Form\Type\LocaleAddressType
        tags:
            - { name: form.type }

LocaleAddress.

$build->add('localeAddress', LocaleAddressType::class);

\Locale::setDefault .

(, , , , ) (PHP/SF) (TWIG).

{% block locale_address_widget %}
    {% for fields in config %}
        <div class="row">
        {% set n = 12 // fields|length %}
        {% for field in fields %}
            <div class="col-md-{{ n }}">
                {{ form_row(form[field]) }}
            </div>
        {% endfor %}
        </div>
    {% endfor %}
{% endblock %}

Symfony 3.

+3

:

  • .
  • , , .
  • .
0

Source: https://habr.com/ru/post/1652311/


All Articles