Как заказать перевод с непереведенными полями, используя переводимые расширения доктрины knp с формой перевода A2lix?

Я ищу простой способ редактирования переведенных полей в форме symfony2. Я использую переводимые расширения доктрины knp для перевода сущности. Непереведенные формы смешиваются с переведенными свойствами в особом порядке. Форма должна отображаться (окончание редактирования) только на активном языке. Например:

 $builder
 ->add('key')
 ->add('translate1','text',array(
    'property_path' => 'translations[de].translate1',
 ))
 ->add('mynumber')
 ->add('translate2','text',array(
    'property_path' => 'translations[de].translate2',
))

Если язык translations[de] не существует, я получаю сообщение об ошибке: «Не удается прочитать свойство «translate1» из массива...»

Форма перевода A2LiX не является решением, потому что она отображает все переводимые поля в одном списке.

Любые идеи?


person Hauke    schedule 07.04.2015    source источник
comment
Форма перевода A2LiX — это решение (не совсем понятно для вашего конкретного варианта использования), но вы должны внимательно прочитать документы, чтобы узнать, как манипулировать полями перевода, и, в конечном итоге, применить небольшой обходной путь для ваших нужд (и взглянуть на исходный код чтобы увидеть, как это работает).   -  person gp_sflover    schedule 07.04.2015
comment
Без понятия, как это должно работать. Даже если я изменю список полей в A2LiX - в списке конструктора будет только один ключ перевода. $formMapper-›добавить('переводы', 'a2lix_translations');   -  person Hauke    schedule 07.04.2015


Ответы (2)


Если вам нужно отобразить поля формы в определенном порядке (используя A2lix), вы можете сделать это, как в этом примере:

$builder
     ->add('key')
     ->add('mynumber')
     ->add('translations', 'a2lix_translations', [
         'required_locales' => ['de'], <-- your current locale
             'fields'           => [
                 'translate1' => [
                     # your field options
                 ],
                 'translate2' => [
                     # your field options
                 ],
    ))

Затем в представлении:

{% import "A2lixTranslationFormBundle::macros.html.twig" as a2lixTranslations %}

{{ form_errors(form_edit) }}
{{ form_start(form_edit) }}
{{ form_row(form_edit.key) }}    
{{ a2lixTranslations.partialTranslations(form_edit.translations, ['translate1']) }}
{{ form_row(form_edit.mynumber) }}
{{ a2lixTranslations.partialTranslations(form_edit.translations, ['translate2']) }}
{{ form_end(form_edit) }}
person gp_sflover    schedule 07.04.2015
comment
Отлично - работает как шарм! Никогда раньше не видел partialTranslations. - person Hauke; 09.04.2015
comment
@Hauke ​​Рад быть полезным :-) - person gp_sflover; 09.04.2015
comment
@gp_slover: все работает, спасибо. Но есть ли способ иметь только одну вкладку сверху для всех полей (перевод и общие поля)? Вот мой пост stackoverflow.com/questions/29621412/. Спасибо - person Benjamin Lucas; 14.04.2015

На самом деле я решил свою проблему с помощью пользовательского типа from с двумя прослушивателями событий для установки и получения значений перевода:

  /**
 * build fields
 * @param \Symfony\Component\Form\FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{

    /**
     * merge new translation
     */ 

    $builder->addEventListener(FormEvents::SUBMIT, function(FormEvent $event) use ($options) {

        //test
        $form = $event->getForm();//form
        $data = $event->getData();//products

        $newTranslation = $event->getData();

        $key=$options['translation_property'];

        $lang=$this->getLocale($options);

        $entity=$form->getParent()->getData();

        $setter='set'.strtoupper($key);
        $getter='get'.strtoupper($key);

        $entity->translate($lang)->$setter($newTranslation);
        $entity->mergeNewTranslations();
     });

    /**
     * Populate with data
     */ 
    $builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) use ($options) {

        $data = $event->getData();//products
        $form = $event->getForm();//form

        $key=$options['translation_property'];
        $lang=$this->getLocale($options);

        $entity=$form->getParent()->getData();

        $setter='set'.strtoupper($key);
        $getter='get'.strtoupper($key);

        $oldValue=$entity->translate($lang,false)->$getter();//no fallback

        $event->setData($oldValue);

    });
}

Поля не сопоставлены. Имя свойства перевода и язык могут быть предоставлены напрямую.

 /**
 * Defauls
 * @param \Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'translation_path'=>'translations',
        'translation_property' => null,
        'translation_lang'=>null,//getLocale or set in form type
        'mapped'=>false     
    ));
}

И тип наследует основной текст.

public function getParent()
{
    return 'text';
}

После определения его как службы расширения ветки (translation_text) вы можете легко использовать его:

 $builder
        ->add('name')           
        ->add('key')            
        ->add('translate1', 'translation_text',
            array(
                    'translation_property'=>'translate1',
                    'translation_lang'=>null
            ))  
person Hauke    schedule 09.04.2015