问题
With Symfony I'm aware that you can create translation files in which you specify the text for different languages etc. This works great for form labels, and other static text across an application.
What I'm wondering though is how you could achieve internationalisation with dynamic content. For example if you have a Product
entity with a description
field. The administrator can alter this text through the back-end.
So how would you implement the international alternatives for dynamic text?
回答1:
You need to create two necessary entity files, first is EntityName, second is EntityNameTranslation. Please look at the example below.
Category Entity
Bundle document: https://github.com/KnpLabs/DoctrineBehaviors
<?php
namespace BundleName\Entity;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
/**
* @ORM\Entity
*/
class Category
{
use ORMBehaviors\Translatable\Translatable;
/**
* @ORM\Column(type="string", length=255)
*/
protected $someFieldYouDoNotNeedToTranslate;
// or do it with PropertyAccessor that ships with Symfony SE
// if your methods don't take any required arguments
public function __call($method, $arguments)
{
return \Symfony\Component\PropertyAccess\PropertyAccess::createPropertyAccessor()->getValue($this->translate(), $method);
}
}
CategoryTranslation Entity
<?php
namespace BundleName\Entity;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
/**
* @ORM\Entity
*/
class CategoryTranslation
{
use ORMBehaviors\Translatable\Translation;
/**
* @ORM\Column(type="string", length=255)
*/
protected $name;
/**
* @ORM\Column(type="string", length=255)
*/
protected $description;
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string
* @return null
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* @param string
* @return null
*/
public function setDescription($description)
{
$this->description = $description;
}
}
Setting and Persisting
<?php
$category = new Category;
$category->translate('fr')->setName('Chaussures');
$category->translate('en')->setName('Shoes');
$em->persist($category);
// In order to persist new translations, call mergeNewTranslations method, before flush
$category->mergeNewTranslations();
$category->translate('en')->getName();
Translation in Form
Bundle document : https://github.com/a2lix/TranslationFormBundle
Example: https://github.com/emsiemhong/CPF/tree/master/NGS/src/NGS/ContentBundle
<?php
namespace NGS\ContentBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use NGS\ContentBundle\Entity\Article;
class ArticleType extends AbstractType
{
private $translator;
public function __construct(TranslatorInterface $translator) {
$this->translator = $translator;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('translations', 'a2lix_translations', array (
'locales' => array('en', 'km'),
'required_locales' => array('en'),
'label' => false,
'fields' => array(
'title' => array (
'field_type' => 'text',
'label' => $this->translator->trans('title')
),
'description' => array (
'field_type' => 'ckeditor',
'label' => $this->translator->trans('description')
)
),
))
->add('type', 'choice', array(
'choices' => array(
Article::ABOUT_TYPE => $this->translator->trans('about'),
Article::SERVICE_TYPE => $this->translator->trans('service'),
Article::HOME_TYPE => $this->translator->trans('home')
)
))
->add('picture', 'file', array(
'required' => false
))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'NGS\ContentBundle\Entity\Article'
));
}
/**
* @return string
*/
public function getName()
{
return 'ngs_contentbundle_articles';
}
}
Getting
{% block content %}
/*
Because we use the magic function so we don't need specify the language so it will get the current local language
//the magic function
public function __call($method, $arguments)
*/
<span>{{ category.getName }}</span>
<span>{{ category.getDescription }}</span>
{% endblock %}
来源:https://stackoverflow.com/questions/32583444/symfony-translations-on-dynamic-content