Sylius: как правильно отобразить предварительный просмотр изображений на объекте, используя SyliusResourceBundle?

#php #symfony #sylius

#php #symfony #sylius

Вопрос:

У меня есть пользовательский объект, который зарегистрирован как Sylius-Resource. У этого объекта может быть список изображений. Для моего использования я следовал инструкциям в документах.

Я использую подкласс ImageType для предоставления формы загрузки изображения:

ArtistImageType:

 <?php
declare(strict_types=1);

namespace AppBundleFormType;

use SyliusBundleCoreBundleFormTypeImageType;

class ArtistImageType extends ImageType
{
    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix(): string
    {
        return 'artist_image';
    }
}
  

Вот как я повторно использую этот ArtistImageType в моем FormType:

 final class ArtistType extends AbstractResourceType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class, [
                'empty_data' => '',
            ])
            ->add('firstName', TextType::class, [
                'empty_data' => '',
                'required' => false,
            ])
            ->add('lastName', TextType::class, [
                'empty_data' => '',
            ])

            ->add('images', CollectionType::class, [
                'entry_type' => ArtistImageType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false,
                'label' => 'app.images',
            ])
  

И form.html.twig:

 <div class="ui two column stackable grid">
    {{ form_errors(form) }}
    <div class="column">
        <div class="ui segment">
            <h4 class="ui dividing header">{{ 'sylius.ui.general_info'|trans }}</h4>
            <div class="two fields">
                {{ form_row(form.name) }}
            </div>

            {{ form_row(form.images) }}

        </div>
        <div class="ui segment">
            {{ form_row(form.firstName) }}
            {{ form_row(form.lastName) }}
        </div>
    </div>
  

Мне интересно, как я мог бы отобразить изображения, которые уже были загружены в существующий объект, аналогичный форме продукта, где существующие изображения отображаются рядом с кнопкой «выбрать файл»?

Это то, чего я хочу достичь:

введите описание изображения здесь

Но он все равно отображается без предварительного просмотра. По-видимому, необходимы некоторые дополнительные настройки.

введите описание изображения здесь

Ответ №1:

После прочтения кода Sylius я могу ответить сам:

1. ArtistType::buildForm()

Нам нужно добавить атрибут entry_options , чтобы передать объект Artist-Entity в ImageType:

         ->add('images', CollectionType::class, [
            'entry_type' => ArtistImageType::class,
            'allow_add' => true,
            'allow_delete' => true,
            'by_reference' => false,
            'entry_options' => ['artist' => $options['data']],
            'label' => 'app.images',
  

2. ArtistImageType

Затем мы сделали ArtistImageType подходящим для правильной обработки этого атрибута:

 class ArtistImageType extends ImageType
{

    public function buildView(FormView $view, FormInterface $form, array $options): void
    {
        parent::buildView($view, $form, $options);

        $view->vars['artist'] = $options['artist'];
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        parent::configureOptions($resolver);

        $resolver->setDefined('artist');
        $resolver->setAllowedTypes('artist', Artist::class);
    }


    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix(): string
    {
        return 'artist_image';
    }
}
  

Рассмотрим getBlockPrefix -метод.

3. Форма-Тема:

Создайте форму-тему для раздела изображений:

 {% extends '@SyliusUi/Form/imagesTheme.html.twig' %}

{% block artist_image_widget %}
    {% spaceless %}
        <div class="ui upload box segment">
            {{ form_row(form.type) }}
            <label for="{{ form.file.vars.id }}" class="ui icon labeled button"><i class="cloud upload icon"></i> {{ 'sylius.ui.choose_file'|trans }}</label>
            {% if form.vars.value.path|default(null) is not null %}
                <img class="ui small bordered image" src="{{ form.vars.value.path|imagine_filter('sylius_small') }}" alt="{{ form.vars.value.type }}" />
            {% endif %}
            <div class="ui hidden element">
                {{ form_widget(form.file) }}
            </div>
            <div class="ui element">
                {{- form_errors(form.file) -}}
            </div>
        </div>
    {% endspaceless %}
{% endblock %}
  

Рассмотрим имя блока artist_image_widget . Это связующее звено между Twig и getBlockPrefix-функцией ImageType-implementation.

4. Я поместил весь материал раздела изображения в отдельный файл:

_media.html.twig :

 {% form_theme form '@AppBundle/Form/imagesTheme.html.twig' %}

<div class="ui" >
    <h3 class="ui dividing header">{{ 'sylius.ui.media'|trans }}</h3>
    <br>
    {{ form_row(form.images, {'label': false}) }}

</div>
  

Окончательная форма:

 <div class="column">
    <div class="ui segment">
        <h4 class="ui dividing header">{{ 'sylius.ui.general_info'|trans }}</h4>
        <div class="two fields">
            {{ form_row(form.name) }}
        </div>

        {% include 'AppBundle:Admin:_media.html.twig' %}

    </div>
    <div class="ui segment">
        {{ form_row(form.firstName) }}
        {{ form_row(form.lastName) }}
    </div>
  

Ответ №2:

я думаю, что 3.Form-Theme, опубликованная @itinance, действительно исправляет это (путем копирования содержимого виджета вместо form_row (form.images ..) мне также удается заставить это работать). Но, к сожалению, я не смог заставить его работать с расширением «@SyliusUi /Form /imagesTheme.html.twig», даже когда getBlockPrefix возвращает соответствующий префикс для этого префикса