title: Sylius: adding resource with translateable content
body: <p>I am building an app based on Sylius standard edition. With the ResourceBundle i handled to integrate my own entities and the corresponding relations. This new resources should be related later to the products entity, but first i want to get it working "standalone". The backend works for both, the added resource and for relations. These are editable via form-collections. Very fine! Now i want to get translated database-content for my new resource. I tried the way i did it in Symfony earlier, but it didn't work. The last vew days i tried every possible solution found, but none of this works, or i made mistakes... Neither the translation-tables where constructed when typing:</p>
  
  <pre><code>app/console doctrine:schema:update --force
  </code></pre>
  
  <p>nor translatable content is visible in the forms. When calling the edit action, i get following error:</p>
  
  <pre><code>error:
  Neither the property "translations" nor one of the methods "getTranslations()", "translations()", "isTranslations()", "hasTranslations()", "__get()" exist and have public access in class "KontaktBundle\Entity\Kontakte".
  </code></pre>
  
  <p>Is somebody out there with an example implementation of a extended Sylius-resource with translateable database-content? I'm still learning symfony and sylius too, can you tell me what i'm missing or doing wrong?</p>
  
  <h2>Many Thanks to @gvf. Now i figured out that the config entry must be set. This gave me a functional example which i want to provide here:</h2>
  
  <h2>Configs</h2>
  
  <pre><code># app/config/sylius_config.yml (must be imported in config)
  
  # Adding Resource
  sylius_resource:
      # Resource Settings
      settings:
          sortable: true
          paginate: 50
          allowed_paginate: [50, 100, 500]
          filterable: true
  
      resources:
          dbk.authors:
              driver: doctrine/orm
              templates: AuthorBundle:Backend
              object_manager: default
              classes:
                  model: AuthorBundle\Entity\Kontakte
                  #interface: // if you have an interface configured
                  controller: Sylius\Bundle\ResourceBundle\Controller\ResourceController
                  repository: Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository
                  translation:
                      model: AuthorBundle\Entity\AuthorsTranslation
                      mapping:
                          fields: ['anrede','biografie']
  </code></pre>
  
  <h2>Services</h2>
  
  <pre><code># app/config/sylius_services.yml (must be imported in config)
  parameters:
      # Parameter for our author entity
      app.form.type.authors.class: AuthorBundle\Form\AuthorsType
      app.form.type.authors_translation.class: AuthorBundle\Form\AuthorsTranslationType
  
  services:
      # Adding Authors Backend menu Item
      dbk_backend_authors.menu_builder:
          class: AuthorBundle\EventListener\MenuBuilderListener
          tags:
              - { name: kernel.event_listener, event: sylius.menu_builder.backend.main, method: addBackendMenuItems }
              - { name: kernel.event_listener, event: sylius.menu_builder.backend.sidebar, method: addBackendMenuItems }
  
      # Adding Authors FormType
      app.form.type.authors:
          class: "%app.form.type.authors.class%"
          tags: 
              - {name: form.type, alias: dbk_authors }
  
      app.form.type.authors_translation:
          class: "%app.form.type.authors_translation.class%"
          tags: 
              - {name: form.type, alias: dbk_authors_translation }
  </code></pre>
  
  <h2>EventListener (Adds Menu Entry in Sylius-Backend)</h2>
  
  <pre><code>&lt;?php
  
  // AuthorBundle/EventListener/MenuBuilderListener/MenuBuilderListener.php
  
  namespace AuthorBundle\EventListener;
  
  use Sylius\Bundle\WebBundle\Event\MenuBuilderEvent;
  
  class MenuBuilderListener
  {
      public function addBackendMenuItems(MenuBuilderEvent $event)
      {
          $menu = $event-&gt;getMenu();
  
          $menu['assortment']-&gt;addChild('vendor', array(
              'route' =&gt; 'Authors',
              'labelAttributes' =&gt; array('icon' =&gt; 'glyphicon glyphicon-user'),
          ))-&gt;setLabel('Authors');
      }
  }
  </code></pre>
  
  <h2>Entities</h2>
  
  <h3>Authors (The new resource hich we want to add and to translate)</h3>
  
  <pre><code>&lt;?php
  
  // AuthorBundle/Entity/Authors.php
  
  namespace AuthorBundle\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  use Sylius\Component\Translation\Model\AbstractTranslatable;
  use Doctrine\Common\Collections\ArrayCollection;
  
  /**
   * Authors
   *
   * @ORM\Entity
   * @ORM\Table(name="authors")
   */
  class Authors extends AbstractTranslatable
  {
  
      //
      // IDENTIFIER FIELDS
      //
  
      /**
       * @var integer
       *
       * @ORM\Column(name="id", type="bigint", length=20, nullable=false, options={"unsigned":"true"})
       * @ORM\Id
       * @ORM\GeneratedValue(strategy="AUTO")
       */
      private $id;
  
  
      //
      // FIELDS
      //
  
      /**
       * @var string
       *
       * @ORM\Column(name="vorname", type="string", length=255)
       */
      private $vorname;
  
      /**
       * @var string
       *
       * @ORM\Column(name="nachname", type="string", length=255)
       */
      private $nachname;
  
      public function __construct() {
          parent::__construct();
      }
  
      //
      // TranslationFields - Getters and Setters
      //
  
      /**
       * Get Anrede
       * @return string
       */
      public function getAnrede()
      {
          return $this-&gt;translate()-&gt;getAnrede();
      }
  
      /**
       * Set Anrede
       *
       * @param string $anrede
       *
       * @return Authors
       */
      public function setAnrede($anrede)
      {
          $this-&gt;translate()-&gt;setAnrede($anrede);
          return $this;
      }
  
      /**
       * Get Biografie
       * @return string
       */
      public function getBiografie()
      {
          return $this-&gt;translate()-&gt;getBiografie();
      }
  
      /**
       * Set Biografie
       *
       * @param string $biografie
       *
       * @return Authors
       */
      public function setBiografie($biografie)
      {
          $this-&gt;translate()-&gt;setBiografie($biografie);
          return $this;
      }
  
  
      //
      // Getters and Setters
      //
  
      /**
       * Get id
       *
       * @return integer
       */
      public function getId()
      {
          return $this-&gt;id;
      }
  
  
      /**
       * Set vorname
       *
       * @param string $vorname
       *
       * @return Authors
       */
      public function setVorname($vorname)
      {
          $this-&gt;vorname = $vorname;
  
          return $this;
      }
  
      /**
       * Get vorname
       *
       * @return string
       */
      public function getVorname()
      {
          return $this-&gt;vorname;
      }
  
      /**
       * Set nachname
       *
       * @param string $nachname
       *
       * @return Authors
       */
      public function setNachname($nachname)
      {
          $this-&gt;nachname = $nachname;
  
          return $this;
      }
  
      /**
       * Get nachname
       *
       * @return string
       */
      public function getNachname()
      {
          return $this-&gt;nachname;
      }
  
  
      public function  __toString(){
          return $this-&gt;getFullName();
      }
  
  }
  </code></pre>
  
  <h3>AuthorsTranslation (This is the Entity for tanslation of Authors)</h3>
  
  <pre><code>&lt;?php
  
  // AuthorBundle/Entity/AuthorsTranslation.php
  
  namespace AuthorBundle\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  use Sylius\Component\Translation\Model\AbstractTranslation;
  
  /**
   * AuthorsTranslation
   *
   * @ORM\Entity
   * @ORM\Table(name="authors_translation")
   */
  class AuthorsTranslation extends AbstractTranslation
  {
      /**
       * @var integer
       *
       * @ORM\Column(name="id", type="bigint", length=20, nullable=false, options={"unsigned":"true"})
       * @ORM\Id
       * @ORM\GeneratedValue(strategy="AUTO")
       */
      protected $id;
  
      //
      // TRANSLATABLE - FIELDS
      //
  
      /**
       * @var string
       * @ORM\Column(name="anrede", type="string", length=255)
       */
      private $anrede;
  
      /**
       * @var string
       * @ORM\Column(name="biografie", type="text")
       */
      private $biografie;
  
      /**
       * {@inheritdoc}
       */
      public function getId()
      {
          return $this-&gt;id;
      }
  
      //
      // GETTERS AND SETTERS
      //
  
      /**
       * Set anrede
       *
       * @param string $anrede
       * @return Authors
       */
      public function setAnrede($anrede)
      {
          $this-&gt;anrede = $anrede;
          return $this;
      }
  
      /**
       * Get anrede
       *
       * @return string
       */
      public function getAnrede()
      {
          return $this-&gt;anrede;
      }
  
  
      /**
       * Set biografie
       *
       * @param string $biografie
       *
       * @return Authors
       */
      public function setBiografie($biografie)
      {
          $this-&gt;biografie = $biografie;
          return $this;
      }
  
      /**
       * Get biografie
       *
       * @return string
       */
      public function getBiografie()
      {
          return $this-&gt;biografie;
      }
  
  
  
  }
  </code></pre>
  
  <h2>FormTypes</h2>
  
  <h3>AuthorsType</h3>
  
  <pre><code>&lt;?php
  
  // AuthorBundle/Form/AuthorsType.php
  
  namespace AuthorBundle\Form;
  
  use Symfony\Component\Form\AbstractType;
  use Symfony\Component\Form\FormBuilderInterface;
  use Symfony\Component\OptionsResolver\OptionsResolverInterface;
  use Doctrine\ORM\QueryBuilder;
  
  class AuthorsType extends AbstractType
  {
  
       /**
       * @param FormBuilderInterface $builder
       * @param array $options
       */
      public function buildForm(FormBuilderInterface $builder, array $options)
      {
          $builder
              // Add Translations to Form.
              -&gt;add('translations', 'a2lix_translations', array(
                  'required' =&gt; false,
                  'fields' =&gt; array(
                      'anrede' =&gt; array(
                          'label' =&gt; 'Anrede',
                      ),
                      'biografie' =&gt; array(
                          'label' =&gt; 'Biografie',
                          'attr' =&gt; array('data-edit' =&gt; 'wysiwyg', 'rows' =&gt; '15'),
                          'required' =&gt; false,
                      )
                  )
              ))
  
              -&gt;add('vorname', null, array(
                  'label' =&gt; 'Vorname',
                  'required' =&gt; false,
              ))
  
              -&gt;add('nachname', null, array(
                  'label' =&gt; 'Nachname',
                  'required' =&gt; false,
              ))
          ;
      }
  
      /**
       * @param OptionsResolverInterface $resolver
       */
      public function setDefaultOptions(OptionsResolverInterface $resolver)
      {
              $resolver-&gt;setDefaults(array(
                  'csrf_protection'   =&gt; false,
                  'data_class' =&gt; 'AuthorBundle\Entity\Authors'
              ));
      }
  
      /**
       * @return string
       */
      public function getName()
      {
          return 'dbk_authors';
      }
  }
  </code></pre>
  
  <h3>AuthorsTranslationType</h3>
  
  <pre><code>&lt;?php
  
  // AuthorBundle/Form/AuthorsTranslationType.php
  
  namespace AuthorBundle\Form;
  
  use Symfony\Component\Form\AbstractType;
  use Symfony\Component\Form\FormBuilderInterface;
  
  class AuthorsTranslationType extends AbstractType
  {
      /**
       * {@inheritdoc}
       */
      public function buildForm(FormBuilderInterface $builder, array $options)
      {
          $builder
              -&gt;add('anrede', 'text', array(
                  'label' =&gt; 'Anrede'
              ))
              -&gt;add('biografie', 'textarea', array(
                  'label' =&gt; 'Biografie'
              ))
          ;
      }
  
      /**
       * {@inheritdoc}
       */
      public function getName()
      {
          return 'dbk_authors_translation';
      }
  }
  </code></pre>
  
  <h2>Form Template</h2>
  
  <pre><code>{# AuthorBundle/Resources/views/backend/edit||add.html.twig - as you like... the call of form.translation (line 5) is the point here #}
  {% form_theme form 'SyliusWebBundle:Backend:forms.html.twig' %}
  &lt;div class="row"&gt;
      &lt;div class="col-md-12"&gt;
          {{ form_row(form.translations, {'attr': {'class': 'input-lg'}}) }}
          {{ form_row(form.vorname) }}
          {{ form_row(form.nachname) }}
      &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>