steff81/translation-bundle

Symfony2 和 Doctrine 2 的翻译包

安装: 10

依赖者: 0

建议者: 0

安全: 0

星标: 0

关注者: 1

分支: 3

类型:symfony-bundle

dev-master 2013-03-20 13:36 UTC

This package is not auto-updated.

Last update: 2024-09-22 04:24:30 UTC


README

A Symfony2 bundle for translating Doctrine2 entities Travis build status

如何安装

所见即所得

<?php
$book = new Cypress\MyBundle\Entity\Book();
// setters
$book->setTitle('the lord of the rings');
$book->setTitleEs('el señor de los anillos');
$book->setTitleIt('il signore degli anelli');
// getters
$book->getTitle();
$book->getTitleEs();
// etc...

在你的 twig 模板中

<h1>{{ book|translate('title') }}</h1>
<h1>{{ book|translate('title', 'es') }}</h1>

配置

假设你有一个 Book 实体,具有标题属性

<?php
namespace Cypress\MyBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Books
 *
 * @ORM\Entity
 * @ORM\Table(name="book")
 */
class Book
{
    /**
     * @var integer
     *
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column
     */
    private $title;

    // constructor, getter, setter and others amenities...
}

为了翻译它

  • 创建 BookTranslations 类(选择你想要的名称),并使其继承 TranslationEntity 父类。您必须定义 $object 属性,该属性与您的 Book 主类具有多对一关系
<?php
namespace Cypress\MyBundle\Entity;

use Cypress\TranslationBundle\Entity\Base\TranslationEntity;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="book_translations",
 *     uniqueConstraints={@ORM\UniqueConstraint(name="lookup_unique_idx", columns={
 *         "locale", "object_id", "field"
 *     })}
 * )
 */
class BookTranslations extends TranslationEntity
{
    /**
     * @var Book
     *
     * @ORM\ManyToOne(targetEntity="Cypress\MyBundle\Entity\Book", inversedBy="translations")
     * @ORM\JoinColumn(onDelete="CASCADE")
     */
    protected $object;
}

您可能希望更改的合理部分是:命名空间表名索引名目标实体

不要更改 inversedBy 属性!是的,这是您的类,但请不要在此处添加属性,而应在主类中添加!

  • TranslatableEntity 父类添加到您的 Book 实体中,定义一个 translations 属性,该属性与翻译实体具有一对多关系,并实现三个抽象方法
<?php
namespace Cypress\MyBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Cypress\TranslationBundle\Entity\Base\TranslatableEntity;

/**
 * Books
 *
 * @ORM\Entity
 * @ORM\Table(name="book")
 */
class Book extends TranslatableEntity
{
    /**
     * @var integer
     *
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column
     */
    protected $title;

    /**
     * @var string
     *
     * @ORM\OneToMany(targetEntity="Cypress\MyBundle\Entity\BookTranslations", mappedBy="object", cascade={"all"})
     */
    protected $translations;

    // constructor, getter, setter and others amenities...

    /**
     * get the name of the TranslationEntity
     *
     * @return mixed
     */
    public function getTranslationEntity()
    {
        return 'Cypress\MyBundle\Entity\BookTranslations';
    }

    /**
     * get the default language
     *
     * @return string
     */
    public function getDefaultLanguage()
    {
        return 'en';
    }

    /**
     * get an array of supported languages
     *
     * @return array
     */
    public function getOtherLanguages()
    {
        return array('it', 'es');
    }
}

getTranslationEntity:返回一个字符串,其中包含翻译实体的完全限定名称

getDefaultLanguage:返回一个字符串,其中包含主语言的两位数代码

getOtherLanguages:返回一个包含其他语言两位数代码的数组

小心!!:您需要将具有翻译的属性设置为 protected 而不是 private 或不设置。

  • 重建你的模型
$ ./app/console doctrine:schema:update --force

重要

如果您的可翻译实体包含构造函数,请记得调用父类构造函数或将 translations 属性设置为空的 ArrayCollection。例如

<?php
class Book extends TranslatableEntity
{
    // properties

    public function __contruct()
    {
        // call the parent constructor
        parent::__construct();
        // or alternatively, set the translations property
        $this->translations = new ArrayCollection();
        // your logic ...
    }
}

你完成了!

MongoDB

阅读关于 MongoDB ODM 的文档 这里

用法

<?php
$book = new Cypress\MyBundle\Entity\Book();
$book->setTitle('the lord of the rings'); // default language defined in getDefaultLanguage()
$book->setTitleEn('the lord of the rings'); // same as before
$book->setTitleEs('el señor de los anillos'); // set the title in spanish
$book->setTitleIt('il signore degli anelli'); // guess?
$book->setTitleRu('some weird letters here'); // throws an exception!

$em->persist($book); // $em is a doctrine entity manager
$em->flush(); // if you WTF on this go read the doctrine docs... :)

// now retrieve
echo $book->getTitle(); // the lord of the rings
echo $book->getTitleEn(); // the lord of the rings
echo $book->getTitleIt(); // il signore degli anelli...
// and so on...

您可以为您的属性使用任何命名约定,下划线和 camelCase,只要您为属性定义 getter/setter 即可

Twig

在您的 twig 模板中,您可以使用一个漂亮的过滤器

{% for book in books %}
    <h1>{{ book|translate('title') }}</h1>
    <p>{{ book|translate('description') }}</p>
{% endfor %}

请记住直接将过滤器应用于 TranslatableEntity 实例,并将属性名称设置为过滤器参数

默认情况下,twig 从当前环境(sf 2.0 中的会话和在 sf 2.1 中的请求)获取语言,但您也可以使用 twig 强制设置语言,只需将两位数代码作为过滤器的第二个参数传递即可

<h1>{{ book|translate('title') }}</h1>
<h2>spanish translation: {{ book|translate('title', 'es') }}</h2>
<h2>italian translation: {{ book|translate('title', 'it') }}</h2>

在某些情况下,您不知道要调用对象的哪个方法。例如,一个菜单,其中声音是不同类型的对象,具有 "title" 和 "name" 作为主要翻译属性。在这种情况下,您也可以将数组作为属性名称传递。首先匹配的获胜。

<ul>
    {% for menu_voice in menu_voices %}
    <li>{{ menu_voice|translate(['title', 'name'], 'es') }}</li>
    {% endfor %}
</ul>

如果您不使用 twig,请将此添加到您的配置文件中

cypress_translation:
    twig: false

Sonata

此捆绑包与 sonata admin 捆绑包配合得很好。只需在您的管理类中命名属性即可

<?php
namespace Sonata\NewsBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;

class TagAdmin extends Admin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('title')
            ->add('title_it', 'text')
            ->add('title_es', 'text')
            ->add('myAwesomeDescription_es', 'text')
        ;
    }
}

您只需要定义字段类型,因为sonata无法在不存在属性上猜测类型。

小心

请为您的语言使用两位数字代码。例如:"en","it" 或 "es"。

"en_US" 不适用!

测试

此捆绑包已使用phpunit进行单元测试。这里是travis构建页面