steff81 / translation-bundle
Symfony2 和 Doctrine 2 的翻译包
Requires
- php: >=5.3.3
- doctrine/doctrine-bundle: >=1.2
- doctrine/orm: >=2.2.3,<2.5-dev
Requires (Dev)
- twig/twig: 1.9.*
This package is not auto-updated.
Last update: 2024-09-22 04:24:30 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 主类具有多对一关系
<?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构建页面