cypresslab/translation-bundle

Symfony2 和 Doctrine 2 的翻译包

dev-master 2013-08-27 06:05 UTC

This package is auto-updated.

Last update: 2024-08-30 13:23:32 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 类有一个 ManyToOne 关系
<?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 实体中,定义一个与翻译实体 OneToMany 关系的 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...

你可以为你的属性使用任何命名约定,下划线或驼峰式,只要为属性定义 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 bundle 一起工作得很好 只需在 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构建页面