简体   繁体   中英

Symfony2: 1 form to edit a translatable entity

I have a translatable entity using the translatable behaviour of doctrine2.

I'm trying to build a form that looks like this:

   | French |English| Spanish |
+--+--------|       |---------+------------+
|                                          |
| name:  [___my_english_name___]           |
|                                          |
| title: [___my_english_title__]           |
|                                          |
+------------------------------------------+

Order:  [___1___]
Online: (x) Yes
        ( ) No

So basically, there are the order & online attributes of the object that are not translatable, and the name & title attribute that have the translatable behaviour.

In case my drawing is not clear: the form contain a 1 tab per locale that hold the field that are translatable.

The problem I have is that by default, Symfony2 bind a form to an entity, but the doctrine translatable behaviour force me to have one entity per locale. Personally the doctrine behaviour is fine (and I like it), but I'm unable to make a form that allow me to edit the entity in all the locale -- in the same form.

So far, I've the main form:

namespace myApp\ProductBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

/**
 * Form for the productGroup.
 */
class ProductType extends AbstractType
{
    /**
     * Decide what field will be present in the form.
     *
     * @param FormBuilder $builder FormBuilder instance.
     * @param array       $options Custom options.
     *
     * @return null;
     */
    public function buildForm(FormBuilder $builder, array $options)
    {
        //Todo: get the available locale from the service.
        $arrAvailableLocale = array('en_US', 'en_CA', 'fr_CA', 'es_ES');

        //Render a tab for each locale
        foreach ($arrAvailableLocale as $locale) {
            $builder->add(
                'localeTab_' . $locale,
                new ProductLocaleType(),
                array('property_path' => false, //Do not map the type to an attribute.
                     ));
        }


        //Uni-locale attributes of the entity.
        $builder
            ->add('isOnline')
            ->add('sortOrder');


    }

    /**
     * Define the defaults options for the form building process.
     *
     * @param array $options Custom options.
     *
     * @return array Options with the defaults values applied.
     */
    public function getDefaultOptions(array $options)
    {
        return array(
            'data_class' => 'myApp\ProductBundle\Entity\Product',
        );
    }

    /**
     * Define the unique name of the form.
     *
     * @return string
     */
    public function getName()
    {
        return 'myapp_productbundle_producttype';
    }
}

And the tab-form:

<?php

namespace MyApp\ProductBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

use invalidArgumentException;

/**
 * Form for the productGroupLocale tabs.
 */
class ProductLocaleType extends AbstractType
{
    /**
     * Decide what field will be present in the form.
     *
     * @param FormBuilder $builder FormBuilder instance.
     * @param array       $options Custom options.
     *
     * @return null;
     */
    public function buildForm(FormBuilder $builder, array $options)
    {


        $builder->add('name', 'text', array('data' => ???));
        $builder->add('title', 'text', array('data' => ???));

    }

    /**
     * Define the defaults options for the form building process.
     *
     * @param array $options Custom options.
     *
     * @return array Options with the defaults values applied.
     */
    public function getDefaultOptions(array $options)
    {
        return array(
            //'data_class' => 'MyApp\ProductBundle\Entity\Product',
            'name' =>  '',
            'title' => '',
        );
    }

    /**
     * Define the unique name of the form.
     *
     * @return string
     */
    public function getName()
    {
        return 'myapp_productbundle_productlocaletype';
    }
}

But as you can't see, I've no idea how to get the name and title values from the translated entity, and neither I know how to persist them once the form will be submitted.

Hi if you use gedmo extensions Translatable is not meant to handle multiple translations per request. Try using knplabs alternative may be a better option to handle it in more general ways.

您可能对TranslationFormBundle感兴趣,它添加了一个表单类型以使用DoctrineTranslatable扩展。

I've check the Translator extension, and even if it's interesting, it wasn't corresponding to our needs. (Basically, all the examples we found require that we change the site locale in order to edit an entity in another locale. I don't know Chinese, and I don't want my interface to be in Chinese, but I do have a translation that I have to copy/paste. Seems weird to explain that as it's really basic in every solid CMS you'll find out there, but I was looking a bit complex to do that kind of CMS functionnality using Symfony.)

So we've developed a solution and builded a BreadGeneratorBundle that we've decide to share: https://github.com/idealtech/BreadGeneratorBundle

At the time of posting this, it still under development, but it can be used as an alternative to the CrudGenerator in order to generate form for translatable entity.

We also manage to use the Gedmo Extension -- even if Gediminas said it's not meant to handle multiple translation ;)

Hope this will help someone ! :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM