cypresslab / translation-bundle
Symfony2 和 Doctrine 2 的翻译包
Requires
- php: >=5.3.3
- doctrine/doctrine-bundle: 1.*
- doctrine/orm: >=2.2,<=2.4
Requires (Dev)
- twig/twig: 1.9.*
This package is auto-updated.
Last update: 2024-08-30 13:23:32 UTC
README
A Symfony2 bundle for translating Doctrine2 entities
所见即所得
<?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构建页面