perfectneeds / locale-bundle
在项目中管理多语言
2.0.8
2022-05-24 14:32 UTC
Requires
- php: ^7.3 || ^8.0
- symfony/framework-bundle: ~4.0|~5.0|~6.0
Requires (Dev)
- doctrine/doctrine-bundle: ~1.8 | ~2.0
- doctrine/orm: ~2.5
- doctrine/persistence: ~2.0
- phpunit/phpunit: ^8.0 | ^9.0
- symfony/symfony: ~4.4 | ~5.0
README
一个非常简单的bundle,允许您翻译实体。
参考仓库。
https://github.com/vm5/EntityTranslationsBundle
安装
- composer require perfectneeds/locale-bundle "~1.0"
- 在AppKernel.php中注册bundle:
new VM5\EntityTranslationsBundle\VM5EntityTranslationsBundle()
- 将LocaleBundle复制到您的项目中
src/PN/Bundle
- 在AppKernel.php中注册bundle:
new PN\LocaleBundle\LocaleBundle()
- 为每种语言添加消息文件到
app/Resources/translations
中,命名为messages.{LOCALE}.php(例如:messages.ar.php) - 您必须在config.yml中添加此代码
parameters: locale: en app.locales: en|ar| doctrine: orm: # search for the "ResolveTargetEntityListener" class for an article about this resolve_target_entities: VM5\EntityTranslationsBundle\Model\Language:
更改API方法中的Locale
$this->get('vm5_entity_translations.translator')->setLocale('ar'); //translate entities $this->get('translator')->setLocale('ar'); // translates messages
路由示例
cms:
resource: "@CMSBundle/Controller/FrontEnd/"
type: annotation
prefix: /{_locale}
defaults: {_locale: '%locale%' }
requirements:
_locale: '%app.locales%'
实体示例
<?php namespace PN\Bundle\CMSBundle\Entity; use Doctrine\ORM\Mapping as ORM; use VM5\EntityTranslationsBundle\Model\Translatable; use PN\LocaleBundle\Model\LocaleTrait; /** * Blogger * * @ORM\HasLifecycleCallbacks * @ORM\Table(name="blogger") * @ORM\Entity(repositoryClass="PN\Bundle\CMSBundle\Repository\BloggerRepository") */ class Blogger implements Translatable { use LocaleTrait; /** * @var int * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var string * * @ORM\Column(name="title", type="string", length=255) */ protected $title; /** * @ORM\OneToMany(targetEntity="PN\Bundle\CMSBundle\Entity\Translation\BloggerTranslation", mappedBy="translatable", cascade={"ALL"}, orphanRemoval=true) */ protected $translations; /** * Now we tell doctrine that before we persist or update we call the updatedTimestamps() function. * * @ORM\PrePersist * @ORM\PreUpdate */ public function updatedTimestamps() { $this->setModified(new \DateTime(date('Y-m-d H:i:s'))); if ($this->getCreated() == null) { $this->setCreated(new \DateTime(date('Y-m-d H:i:s'))); } } /** * Constructor */ public function __construct() { $this->translations = new \Doctrine\Common\Collections\ArrayCollection(); } /** * Get id * * @return int */ public function getId() { return $this->id; } /** * Set title * * @param string $title * * @return Blogger */ public function setTitle($title) { $this->title = $title; return $this; } /** * Get title * * @return string */ public function getTitle() { return !$this->currentTranslation ? $this->title : $this->currentTranslation->getTitle(); } }
在CMSBundle/Entity/Translation
中的BloggerTranslation.php
<?php namespace PN\Bundle\CMSBundle\Entity\Translation; use Doctrine\ORM\Mapping as ORM; use VM5\EntityTranslationsBundle\Model\EditableTranslation; use PN\LocaleBundle\Model\TranslationEntity; /** * @ORM\Entity * @ORM\Table(name="blogger_translations") */ class BloggerTranslation extends TranslationEntity implements EditableTranslation { /** * @var string * * @ORM\Column(name="title", type="string", length=255) */ protected $title; /** * @var * @ORM\Id * @ORM\ManyToOne(targetEntity="PN\Bundle\CMSBundle\Entity\Blogger", inversedBy="translations") */ protected $translatable; /** * @var Language * @ORM\Id * @ORM\ManyToOne(targetEntity="PN\LocaleBundle\Entity\Language") */ protected $language; /** * Set title * * @param string $title * * @return Blogger */ public function setTitle($title) { $this->title = $title; return $this; } /** * Get title * * @return string */ public function getTitle() { return $this->title; } }
然后您可以自己翻译它们
$blogger = new Blogger(); // Arabic $arabicTranslation = new BloggerTranslation(); $arabicTranslation->setLanguage($arabicLanguage); $arabicTranslation->setTitle('Title on arabic'); $blogger->addTranslation($arabicTranslation); // French $frenchTranslation = new BloggerTranslation(); $frenchTranslation->setLanguage($frenchLanguage); $frenchTranslation->setTitle('Title on french'); $blogger->addTranslation($frenchTranslation); $em->persist($blogger); $em->flush();
使用表单轻松翻译实体。
创建BloggerTranslationType类
在CMSBundle/Form/Translation/BloggerTranslationType.php
添加所有可翻译列,如BloggerTranslation.php(实体)
<?php namespace PN\Bundle\CMSBundle\Form\Translation; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class BloggerTranslationType extends AbstractType { /** * {@inheritdoc} */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('title') ; } /** * {@inheritdoc} */ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => \PN\Bundle\CMSBundle\Entity\Translation\BloggerTranslation::class )); } /** * {@inheritdoc} */ public function getBlockPrefix() { return 'pn_bundle_cmsbundle_blogger'; } }
在您的主表单中添加翻译字段到BloggerType.php
<?php namespace PN\Bundle\CMSBundle\Form; use Doctrine\ORM\EntityRepository; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use VM5\EntityTranslationsBundle\Form\Type\TranslationsType; use PN\Bundle\CMSBundle\Form\Translation\BloggerTranslationType; use PN\Bundle\CMSBundle\Entity\BloggerTag; use PN\Bundle\SeoBundle\Form\SeoType; class BloggerType extends AbstractType { /** * {@inheritdoc} */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('title') ->add('publish') ->add('seo', SeoType::class) ->add('post', PostType::class) ->add('translations', TranslationsType::class, [ 'entry_type' => BloggerTranslationType::class, 'entry_language_options' => [ 'en' => [ 'required' => true, ] ], ]) ; } /** * {@inheritdoc} */ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'PN\Bundle\CMSBundle\Entity\Blogger' )); } /** * {@inheritdoc} */ public function getBlockPrefix() { return 'pn_bundle_cmsbundle_blogger'; } }
对于特定区域,将entry_language_options中的required包括在内很重要,因为验证仅在语言不为空或为必填时触发。
如果至少有一个字段被填写,则假定语言不为空。