Doctrine Translatable 不显示语言环境更改的翻译文本

Doctrine Translatable not showing translated text on locale change

我在 Symfony 项目中使用 translatable with doctrine。我已经能够添加可翻译的实体并存储翻译后的文本,但是当我更改网站中的语言环境时,文本不会显示,尽管如果我遍历翻译,我可以看到文本。我想我错过了什么。

树枝代码:

<p>Title: {{ course.getTitle() }}</p>
<p>Translations content:</p>
<ul>
    {% for t in course.getTranslations() %}
        <li>{{  t.getLocale() }}: {{ t.getContent() }}</li>
    {% endfor %}
</ul>

如果我转到 /en/ url 的输出是:

Title: my title in en
Translations content:
es: Mi titulo en ES

但是如果我去 /es/ url:

Title:
Translations content:
es: Mi titulo en ES

可以看到es翻译是有的,但是调用getTitle的时候没有显示。

我有我的 Course 实体和 CourseTranslation 实体来存储翻译。

我还添加了侦听器来设置默认语言环境并检查是否正在执行。

<?php
namespace AppBundle\Listener;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class DoctrineExtensionListener implements ContainerAwareInterface
{
    /**
     * @var ContainerInterface
     */
    protected $container;

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    public function onLateKernelRequest(GetResponseEvent $event)
    {
        $translatable = $this->container->get('gedmo.listener.translatable');
        $translatable->setTranslatableLocale($event->getRequest()->getLocale());
    }
}

课程代码:

/**
 * Course
 *
 * @ORM\Table(name="course")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\CourseRepository")
 */
class Course implements Translatable
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

    /**
     * @ORM\OneToMany(
     *   targetEntity="CourseTranslation",
     *   mappedBy="object",
     *   cascade={"persist", "remove"}
     * )
     */
    private $translations;

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


    /** Translatable operations */
    public function getTranslations()
    {
        return $this->translations;
    }

    public function addTranslation(CourseTranslation $t)
    {
        if (!$this->translations->contains($t)) {
            $this->translations[] = $t;
            $t->setObject($this);
        }
    }
}

课程翻译代码:

<?php
namespace AppBundle\Entity;

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

/**
 * @ORM\Entity
 * @ORM\Table(name="course_translations",
 *     uniqueConstraints={@ORM\UniqueConstraint(name="lookup_unique_idx", columns={
 *         "locale", "object_id", "field"
 *     })}
 * )
 */
class CourseTranslation extends AbstractPersonalTranslation
{
    /**
     * Convenient constructor
     *
     * @param string $locale
     * @param string $field
     * @param string $value
     */
    public function __construct($locale, $field, $value)
    {
        $this->setLocale($locale);
        $this->setField($field);
        $this->setContent($value);
    }

    /**
     * @ORM\ManyToOne(targetEntity="Course", inversedBy="translations")
     * @ORM\JoinColumn(name="object_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $object;
}

服务 yml 代码:

services:
    extension.listener:
        class: AppBundle\Listener\DoctrineExtensionListener
        calls:
            - [ setContainer, [ "@service_container" ] ]
        tags:
            # translatable sets locale after router processing
            - { name: kernel.event_listener, event: kernel.request, method: onLateKernelRequest, priority: -10 }

    gedmo.listener.translatable:
        class: Gedmo\Translatable\TranslatableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ "@annotation_reader" ] ]
            - [ setDefaultLocale, [ %locale% ] ]
            - [ setTranslationFallback, [ false ] ]

对于 2.7.11 版的 Symfony,我添加了以下几行以使 Translatable 工作

 use Gedmo\Mapping\Annotation as Gedmo;

 /**
  * MyEntity
  *
  * @ORM\Table(name="myEntity")
  * @ORM\Entity(repositoryClass="AppBundle\Repository\MyEntityRepository")
  * @Gedmo\TranslationEntity(class="AppBundle\Entity\MyEntityTranslation")
  */
 class MyEntity{

      /**
       * @ORM\OneToMany(
       *   targetEntity="AppBundle\Entity\MyEntityTranslation",
       *   mappedBy="object",
       *   cascade={"persist", "remove"}
       * )
       * @Copy\Collection
       */
      private $translations;

      public function setTranslatableLocale($locale){
           $this->locale = $locale;
      }

      public function getTranslations(){
           return $this->translations;
      }

      public function addTranslation(MyEntityTranslation $t){
           if (!$this->translations->contains($t)) {
                $this->translations[] = $t;
                $t->setObject($this);
           }
      }

      public function setTranslations($translations){
          foreach($translations as $t){
               $this->addTranslation($t);
          }
     }

      public function findTranslation($locale, $field){
           $id = $this->id;
           $existingTranslation = $this->translations ? $this->translations->filter(
                function($object) use ($locale, $field, $id) {
                     return ($object && ($object->getLocale() === $locale) && ($object->getField() === $field));
           })->first() : null;
           return $existingTranslation;
      }

      /**
       * Remove translation
       *
       * @param AppBundle\Entity\MyEntityTranslation $translation
       */
      public function removeTranslation(MyEntityTranslation $translation)
      {
           $this->translations->removeElement($translation);
      }
 }

我的翻译 class 看起来和你的一样。希望对你有帮助。

好的,问题找到了。

在实体 class 中我错过了 @Gedmo\TranslationEntity 所以我的实体必须是:

/**
 * Course
 *
 * @ORM\Table(name="course")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\CourseRepository")
 * @Gedmo\TranslationEntity(class="CourseTranslation")
 */
class Course implements Translatable

@systemasis,我不知道你是否在你的例子中指出了这一点。