如何本地化Symfony2表单?

时间:2016-08-24 09:52:53

标签: forms symfony

我有一个Symfony2表单,用户可以输入一个固定格式的地址,因为我们想在国际上提供我们的软件,我正在寻找在SF中实现这一点的最佳方法。

我们不想制作一个通用的address type,而是希望使用一种通用格式本地化表单作为不支持的语言环境的后备。

我想从表单的处理(PHP / SF)和实际渲染(TWIG)中分离布局和本地化(顺序,分组,标签,翻译,强制和可选字段)。

我想出的是:从数据库模型创建一个address表单类型,其中包含所有可能的字段。通过调用form_widget(form)或在需要时渲染单个字段,自动在树枝中渲染此表单类型。最后;定义"布局"某种配置格式(YML,数组等)的表单,并将默认的TWIG表单呈现扩展为通过所述配置中定义的表单元素进行迭代。

例如,荷兰和美国的地址配置为:

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

稍后我们会在此配置中添加本地化标签,类,可选字段和必填字段等。

现在我们的大问题是:在哪里放置此配置?在finishView类中使用简单数组?将配置放在YML文件中,该文件由需要本地化表单布局的表单类型解析?

感谢遇到此问题的人提供的任何信息。

2 个答案:

答案 0 :(得分:3)

  

稍后我们将为此配置添加本地化标签,类,可选字段和必填字段等。

The localized labels is automatic process可以根据用户的区域设置翻译和转换它们。可以使用约束来解析必填字段。

  

在哪里放置此配置?

在我看来,这应该直接进入实体和表单类型:

您可以创建LocaleAddressType并根据当前“区域设置”值添加这些字段,但首先,您需要拥有一个包含与“地址”方法相关的所有可能字段的实体。

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 %}

代码是基于Symfony3的。

答案 1 :(得分:0)

有很多选择:

  • 您可以为每个国家/地区创建不同的表单类型
  • 您可以创建一个包含所有字段的表单类型,然后使用表单事件删除与当前所选国家/地区无关的字段
  • 您可以为每个国家/地区和一个大表单类型创建不同的视图