英文:
Symfony UX Autocomplete - choice_label with KnpLabs Translatable
问题
自动完成选项标签不翻译
平台为Symfony 6.3,使用UX Autocomplete 2.9
我的问题
我的问题:我有一个Symfony UX Autocomplete表单字段,choice_labels以翻译的形式存储在数据库中。我无法使choice_label的翻译工作。它始终默认为英语(我的默认区域设置)。
我已安装并正常使用了KnpLabs Translatable。
我的当前设置:
- FunctionProfile实体
- FunctionProfileTranslation实体 -> 包含一个翻译的名称字段。
- TrainingPickerType表单 -> 包括FunctionProfileAutocompleteField
- FunctionProfileAutocompleteField -> 包含在TrainingPickerType中
为了确保,以下是实体和表单的代码的部分:
//App\Entity\FunctionProfile.php
namespace App\Entity;
use App\Repository\FunctionProfileRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Entity\TranslatableInterface;
use Knp\DoctrineBehaviors\Model\Translatable\TranslatableTrait;
#[ORM\Entity(repositoryClass: FunctionProfileRepository::class)]
class FunctionProfile implements TranslatableInterface
{
use TranslatableTrait;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
//等等。
public function __toString(): string
{
return $this->translate(null, false)->getName();
}
//等等。
}
它的伙伴:
<?php
namespace App\Entity;
//App\Entity\FunctionProfileTranslation.php
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Entity\TranslationInterface;
use Knp\DoctrineBehaviors\Model\Translatable\TranslationTrait;
#[ORM\Entity]
class FunctionProfileTranslation implements TranslationInterface
{
use TranslationTrait;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private $id;
#[ORM\Column(length: 255)]
private ?string $name = null;
public function getId(): ?int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
}
现在是表单部分,这个主要表单包括不按照我想要的方式工作的子表单字段:
<?php
//App\Form\TrainingPickerType.php
namespace App\Form;
use App\Form\Field\FunctionProfileAutocompleteField;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class TrainingPickerType extends AbstractType
{
private TranslatorInterface $translator;
private UrlGeneratorInterface $router;
public function __construct(TranslatorInterface $translator, UrlGeneratorInterface $router)
{
$this->translator = $translator;
$this->router = $router;
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$locale = $options['locale'];
$builder
->setAction($this->router->generate('app_api_get_training_pick_dialog'))
->add('functionProfile', FunctionProfileAutocompleteField::class, [
'label' => $this->translator->trans('Function Profiles', locale: $locale),
'attr' => ['class' => 'none', 'placeholder' => $this->translator->trans('Start typing or select an option...', locale: $locale),],
'label_attr' => ['class' => 'block text-sm font-medium leading-6 text-white'],
])
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'locale' => null
]);
}
}
这里的表单行为正常,区域设置设置为需要的任何内容,标签都很好地翻译,等等。
这个包括的表单字段是问题所在:
<?php
namespace App\Form\Field;
use App\Entity\FunctionProfile;
use App\Repository\FunctionProfileRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\UX\Autocomplete\Form\AsEntityAutocompleteField;
use Symfony\UX\Autocomplete\Form\ParentEntityAutocompleteType;
#[AsEntityAutocompleteField]
class FunctionProfileAutocompleteField extends AbstractType
{
private RequestStack $requestStack;
public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
}
public function configureOptions(OptionsResolver $resolver)
{
$request = $this->requestStack->getCurrentRequest();
$query = $request->query->get('query');
$locale = $request ? $request->getLocale() : 'nl';
$resolver->setDefaults([
'class' => FunctionProfile::class,
'multiple' => true,
'choice_translation_domain' => true,
'choice_label' => function (FunctionProfile $functionProfile) use ($locale) {
$functionProfile->getTranslations();
return $functionProfile->translate($locale)->getName();
},
'query_builder' => function(FunctionProfileRepository $functionProfileRepository) use ($locale, $query) {
$qb = $functionProfileRepository->createQueryBuilder('functionProfile')
->join('functionProfile.translations', 't', 'WITH', 't.locale = :locale')
->setParameter('locale', $locale);
if (!empty($query)) {
$qb->andWhere('t.name LIKE :search')
->setParameter('search', '%' . $query . '%');
}
return $qb;
},
]);
}
public function buildView(FormView|\Symfony\Component\Form\FormView $view, FormInterface|\Symfony\Component\Form\FormInterface $form, array $options): void
{
$view->vars['attr']['class'] = ''; // 删除任何现有的类
}
public function getParent(): string
{
return ParentEntityAutocompleteType::class;
}
}
当我输入查询时,会进行搜索。自动完成选项会显示出来。但它们始终是英文的,即使我手动设置了不同的区域设置,比如 "nl",结果仍然相同:所有choice_labels都是英文的。
您可能能够提供的任何指导或帮助将不胜感激!
我尝试过的
我已经在KnpLabs translatable文档中搜索解决方案,但没有找到解决方
英文:
Autocomplete choice labels don't translate
Platform is Symfony 6.3, with UX Autocomplete 2.9
My issue
My issue: I have a Symfony UX Autocomplete form field, the choice_labels are stored in translated form in the database. I cannot get the choice_label translation to work. It always defaults to English (my default locale).
I have KnpLabs Translatable installed & working.
My current setup:
- FunctionProfile Entity
- FunctionProfileTranslation Entity -> contains a translated name field.
- TrainingPickerType Form -> includes FunctionProfileAutocompleteField
- FunctionProfileAutocompleteField -> included in TrainingPickerType
Just to make sure, the entities and the forms (removed unneccessary parts of the code):
<?php
//App\Entity\FunctionProfile.php
namespace App\Entity;
use App\Repository\FunctionProfileRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Entity\TranslatableInterface;
use Knp\DoctrineBehaviors\Model\Translatable\TranslatableTrait;
#[ORM\Entity(repositoryClass: FunctionProfileRepository::class)]
class FunctionProfile implements TranslatableInterface
{
use TranslatableTrait;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
//etc.
public function __toString(): string
{
return $this->translate(null, false)->getName();
}
//etc.
And it's friend:
<?php
namespace App\Entity;
//App\Entity\FunctionProfileTranslation.php
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Entity\TranslationInterface;
use Knp\DoctrineBehaviors\Model\Translatable\TranslationTrait;
#[ORM\Entity]
class FunctionProfileTranslation implements TranslationInterface
{
use TranslationTrait;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private $id;
#[ORM\Column(length: 255)]
private ?string $name = null;
public function getId(): ?int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
}
Now for the form part, this main form includes the child form field that's not doing what I want it to do:
<?php
//App\Form\TrainingPickerType.php
namespace App\Form;
use App\Form\Field\FunctionProfileAutocompleteField;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class TrainingPickerType extends AbstractType
{
private TranslatorInterface $translator;
private UrlGeneratorInterface $router;
public function __construct(TranslatorInterface $translator, UrlGeneratorInterface $router)
{
$this->translator = $translator;
$this->router = $router;
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$locale = $options['locale'];
$builder
->setAction($this->router->generate('app_api_get_training_pick_dialog'))
->add('functionProfile', FunctionProfileAutocompleteField::class, [
'label' => $this->translator->trans('Function Profiles', locale: $locale),
'attr' => ['class' => 'none', 'placeholder' => $this->translator->trans('Start typing or select an option...', locale: $locale),],
'label_attr' => ['class' => 'block text-sm font-medium leading-6 text-white'],
])
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'locale' => null
]);
}
}
The form hereabove behaves as it should, the locale is set to whatever it needs to be, labels are translated nicely, etc.
This included form field is the issue:
<?php
namespace App\Form\Field;
use App\Entity\FunctionProfile;
use App\Repository\FunctionProfileRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\UX\Autocomplete\Form\AsEntityAutocompleteField;
use Symfony\UX\Autocomplete\Form\ParentEntityAutocompleteType;
#[AsEntityAutocompleteField]
class FunctionProfileAutocompleteField extends AbstractType
{
private RequestStack $requestStack;
public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
}
public function configureOptions(OptionsResolver $resolver)
{
$request = $this->requestStack->getCurrentRequest();
$query = $request?->query->get('query');
$locale = $request ? $request->getLocale() : 'nl';
$resolver->setDefaults([
'class' => FunctionProfile::class,
'multiple' => true,
'choice_translation_domain' => true,
'choice_label' => function (FunctionProfile $functionProfile) use ($locale) {
$functionProfile->getTranslations();
return $functionProfile->translate($locale)->getName();
},
'query_builder' => function(FunctionProfileRepository $functionProfileRepository) use ($locale, $query) {
$qb = $functionProfileRepository->createQueryBuilder('functionProfile')
->join('functionProfile.translations', 't', 'WITH', 't.locale = :locale')
->setParameter('locale', $locale);
if (!empty($query)) {
$qb->andWhere('t.name LIKE :search')
->setParameter('search', '%' . $query . '%');
}
return $qb;
},
]);
}
public function buildView(FormView|\Symfony\Component\Form\FormView $view, FormInterface|\Symfony\Component\Form\FormInterface $form, array $options): void
{
$view->vars['attr']['class'] = ''; // Remove any existing classes
}
public function getParent(): string
{
return ParentEntityAutocompleteType::class;
}
}
When I enter a query, the search happens. The autocomplete options are presented. But they're always in English, even if I manually set a different locale like "nl", the outcome remains the same: all choice_labels are in English.
Any guidance or help you may be able to provide would be super welcome!
What I have tried
I have searched the KnpLabs translatable docs for solutions, but couldn't find any solutions.
I have verified that (outside of the form field), the translated versions of the entity appear; as an example;
Neatly returns Banana when I run:
$test = $functionProfileRepository->findOneBy(["id" => 187]);
dd($test->translate('en')->getName());
And Banaan when I run:
$test = $functionProfileRepository->findOneBy(["id" => 187]);
dd($test->translate('nl')->getName());
I tried retrieving the choice_labels in a separate function and then add those to the choice_label option, but to no avail.
public function getTranslatedLabel(FunctionProfile $functionProfile)
{
$request = $this->requestStack->getCurrentRequest();
$locale = $request ? $request->getLocale() : 'nl';
return $functionProfile->translate($locale)->getName();
}
I'm sorta out of idea's now.
I know about https://github.com/a2lix/TranslationFormBundle but my colleagues indicated not wanting to use it unless absolutely needed, citing bad experiences with earlier versions of the bundle. But if we must, we will use it.
答案1
得分: 0
我有点愚蠢。我的$request->getLocale()还不粘性。按照这个EventSubscriber的说明,一切都正常工作:https://symfony.com/doc/current/session.html#creating-a-localesubscriber
英文:
Okay, so I was a bit stupid. My $request->getLocale() wasn't sticky yet. Everything works as it should implementing this EventSubscriber: https://symfony.com/doc/current/session.html#creating-a-localesubscriber
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论