Skip to content

Latest commit

 

History

History
301 lines (239 loc) · 7.51 KB

README.md

File metadata and controls

301 lines (239 loc) · 7.51 KB

TranslationFormBundle

What does this bundle?

Offers the possibility to easily manage the translatable fields of your entity with a new form type: 'a2lix_translations'.

Requirements

Installation & Configuration

Add the repository to your composer.json

"a2lix/translation-form-bundle": "dev-master"

Run Composer to install the bundle

php composer.phar update a2lix/translation-form-bundle

Enable the bundle in AppKernel.php

new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(),    // Check its existing or add
new A2lix\TranslationFormBundle\A2lixTranslationFormBundle(),

Configure the bundle in config.yml

# Check its existing or add
stof_doctrine_extensions:
    default_locale: %locale%
    orm:
        default:
            translatable: true

a2lix_translation_form:
    object_manager:             # [optional] Defaults to doctrine.orm.entity_manager. Name of the object manager. For instance, 'doctrine.orm.default_entity_manager' or 'doctrine_mongodb.odm.default_document_manager'
    locales: [fr, es, de]       # [optional] Array of the translation locales (The default locale have to be excluded). Can also be specified in the form builder.
    default_required: false     # [optional] Defaults to false. In this case, translation fields are not mark as required with HTML5.
    use_aop: true               # [optional] Defaults to false.

# Template
twig:
    form:
        resources:
            - 'A2lixTranslationFormBundle::form.html.twig'

Example

Entity

<?php

namespace Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Entity\Product.php
 *
 * @ORM\Table()
 * @Gedmo\TranslationEntity(class="Translation\ProductTranslation")
 */
class Product
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string $title
     *
     * @ORM\Column(name="title", type="string", length=255)
     * @Gedmo\Translatable
     */
    private $title;

    /**
     * @var string $description
     *
     * @ORM\Column(name="description", type="text")
     * @Gedmo\Translatable
     */
    private $description;

    /**
     * @ORM\OneToMany(
     *     targetEntity="Translation\ProductTranslation",
     * 	mappedBy="object",
     * 	cascade={"persist", "remove"}
     * )
     * @Assert\Valid(deep = true)
     */
    private $translations;

    public function __construct()
    {
        $this->translations = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set title
     *
     * @param string $title
     * @return Product
     */
    public function setTitle($title)
    {
        $this->title = $title;
        return $this;
    }

    /**
     * Get title
     *
     * @return string
     */
    public function getTitle()
    {
        return $this->title;
    }

    /**
     * Set description
     *
     * @param string $description
     * @return Product
     */
    public function setDescription($description)
    {
        $this->description = $description;
        return $this;
    }

    /**
     * Get description
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * Set translations
     *
     * @param ArrayCollection $translations
     * @return Product
     */
    public function setTranslations($translations)
    {
        foreach ($translations as $translation) {
            $translation->setObject($this);
        }

        $this->translations = $translations;
        return $this;
    }

    /**
     * Get translations
     *
     * @return ArrayCollection
     */
    public function getTranslations()
    {
        return $this->translations;
    }


}

Personal Translation Entity

<?php

namespace Entity\Translation;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Translatable\Entity\MappedSuperclass\AbstractPersonalTranslation;

/**
 * Entity\Translation\ProductTranslation.php

 * @ORM\Entity
 * @ORM\Table(name="product_translations",
 *   uniqueConstraints={@ORM\UniqueConstraint(name="lookup_unique_idx", columns={
 *     "locale", "object_id", "field"
 *   })}
 * )
 */
class ProductTranslation extends AbstractPersonalTranslation
{
    /**
     * @ORM\ManyToOne(targetEntity="Entity\Product", inversedBy="translations")
     * @ORM\JoinColumn(name="object_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $object;
}

Form

Minimal form example:

$builder
    ->add('title')
    ->add('description')
    ->add('translations', 'a2lix_translations')
;

Advanced form example:

$builder
    ->add('translations', 'a2lix_translations', array(
        'locales' => array('fr', 'es', 'de'),   // [optional|required - depends on the presence in config.yml] See above
        'required' => true,                     // [optional] Overrides default_required if need
        'fields' => array(                      // [optional] Manual configuration of fields to display and options. If not specified, all translatable fields will be display, and options will be auto-detected
            'title' => array(
                'label' => 'name',              // [optional] Custom label. Ucfirst, otherwise
                'type' => 'textarea',           // [optional] Custom type
                **OTHER_OPTIONS**               // [optional] max_length, required, trim, read_only, constraints, ...
            ),
            'description' => array(
                'label' => 'Desc.',              // [optional]
                'locale_options' => array(              // [optional] Manual configuration of field for a dedicated locale -- Higher priority
                    'es' => array(
                        'label' => 'descripción'        // [optional] Higher priority
                        **OTHER_OPTIONS**               // [optional] Same possibilities as above
                    ),
                    'fr' => array(
                        'display' => false              // [optional] Prevent display of the field for this locale
                    )
                )
            ),
        );
    ))
;

Template

Separate the render of the default locale away from tabs of locales translation.

{{ form_widget(form.title) }}
{{ form_widget(form.description) }}

{{ form_widget(form.translations) }}

or group all locales (default and translations) in a tabs way:

{{ form_widget(form.translations, {'fields': [form.title, form.description]}) }}

More help

There is an article with an example on how to manage translations with SonataAdminBundle available on Elao's blog.

Thanks to