Как отобразить текущее изображение над полем загрузки в SonataAdminBundle?

Я использую SonataAdminBundle (с Doctrine2 ORM), и я успешно добавил функцию загрузки файлов в мою модель изображения.

Я хотел бы, чтобы на страницах « Показать» и « Правка» был показан простой <img src="{{ picture.url }} alt="{{ picture.title }} /> чуть выше соответствующего поля формы (при условии, что Редактирование снимка, конечно, не нова), чтобы пользователь мог видеть текущую фотографию и решать, менять ее или нет.

После нескольких часов исследований я не смог понять, как это сделать. Полагаю, мне нужно переопределить какой-то шаблон, но я немного потерял … Может ли кто-нибудь дать мне подсказку?

Спасибо!

Вот соответствующий раздел моего класса PictureAdmin.

 protected function configureFormFields(FormMapper $formMapper) { $formMapper ->add('category', NULL, ['label' => 'Catégorie']) ->add('title', NULL, ['label' => 'Titre']) ->add('file', 'file', ['required' => false, 'label' => 'Fichier']) // Add picture near this field ->add('creation_date', NULL, ['label' => 'Date d\'ajout']) ->add('visible', NULL, ['required' => false, 'label' => 'Visible']) ->add('position', NULL, ['label' => 'Position']); } protected function configureShowFields(ShowMapper $showMapper) { $showMapper ->add('id', NULL, ['label' => 'ID']) ->add('category', NULL, ['label' => 'Catégorie']) ->add('title', NULL, ['label' => 'Titre']) ->add('slug', NULL, ['label' => 'Titre (URL)']) ->add('creation_date', NULL, ['label' => 'Date d\'ajout']) ->add('visible', NULL, ['label' => 'Visible']) ->add('position', NULL, ['label' => 'Position']); // Add picture somewhere } 

Вы можете легко сделать это на странице показа по атрибуту шаблона через $showmapper

 ->add('picture', NULL, array( 'template' => 'MyProjectBundle:Project:mytemplate.html.twig' ); 

и внутри вашего шаблона вы получаете текущий объект, поэтому вы можете вызвать метод get и потянуть путь изображения

 <th>{% block name %}{{ admin.trans(field_description.label) }}{% endblock %}</th> <td> <img src="{{ object.getFile }}" title="{{ object.getTitle }}" /> </br> {% block field %}{{ value|nl2br }}{% endblock %} </td> 

Чтобы показать изображение в режиме редактирования, вы должны переопределить fileType или вам нужно создать свой собственный customType поверх fileType

Существует также некоторый пакет, который имеет такую ​​функциональность, проверяя этот GenemuFormBundle

Мне удалось поместить изображение над полем в форме редактирования. Но мое решение немного специфично, потому что я использую Vich Uploader Bundle для обработки загрузок, поэтому генерация URL-адреса изображения была немного проще благодаря помощникам пакетов.

Давайте посмотрим на мой пример, поле для фильма в фильме. Это часть моего класса admin:

 //MyCompany/MyBundle/Admin/FilmAdmin.php class FilmAdmin extends Admin { protected function configureFormFields(FormMapper $formMapper) { $formMapper ->add('title') .... ->add('poster', 'mybundle_admin_image', array( 'required' => false, )) } 

mybundle_admin_image обрабатывается настраиваемым типом поля, который является только дочерним элементом типа файла, устанавливая его метод getParent : (не забудьте зарегистрировать свой класс типа в качестве службы)

 //MyCompany/MyBundle/Form/Type/MyBundleAdminImageType.php public function getParent() { return 'file'; } 

Затем у меня есть шаблон, который расширяет стилину Sonata по умолчанию, и я включил ее в класс администратора:

 //MyCompany/MyBundle/Admin/FilmAdmin.php public function getFormTheme() { return array('MyCompanyMyBundle:Form:mycompany_admin_fields.html.twig'); } 

И, наконец, у меня есть блок для моего пользовательского типа изображения, который расширяет базовый тип файла:

 //MyCompany/MyBundle/Resources/views/Form/mycompany_admin_fields.html.twig {% block mybundle_admin_image_widget %} {% spaceless %} {% set subject = form.parent.vars.value %} {% if subject.id and attribute(subject, name) %} <a href="{{ asset(vich_uploader_asset(subject, name)) }}" target="_blank"> <img src="{{ asset(vich_uploader_asset(subject, name)) }}" width="200" /> </a><br/> {% endif %} {% set type = type|default('file') %} <input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/> {% endspaceless %} {% endblock %} 

Это приводит к тому, что перед полем загрузки отображается предварительный просмотр изображения размером 200 пикселей (если он существует), связанный с его полноразмерной версией, открывающейся на новой вкладке. Вы можете настроить его так, как хотите, например, добавить плагин lightbox.

вы можете легко сделать это на странице редактирования с помощью помощников (FormMapper-> setHelps) или передать опцию «help» на FormMapper

 protected function configureFormFields(FormMapper $formMapper) { $options = array('required' => false); if (($subject = $this->getSubject()) && $subject->getPhoto()) { $path = $subject->getPhotoWebPath(); $options['help'] = '<img src="' . $path . '" />'; } $formMapper ->add('title') ->add('description') ->add('createdAt', null, array('data' => new \DateTime())) ->add('photoFile', 'file', $options) ; } 

Решение для Symfony3

Ответ от @kkochanski – самый чистый способ, который я нашел до сих пор. Здесь версия портирована на Symfony3 . Я также исправил некоторые ошибки.

Создайте новый шаблон image.html.twig для нового типа формы (полный путь: src/AppBundle/Resources/views/Form/image.html.twig ):

 {% block image_widget %} {% spaceless %} {% set type = type|default('file') %} <input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/> {% if image_web_path is not empty %} <img src="{{ image_web_path }}" alt="image_photo"/> {% endif %} {% endspaceless %} {% endblock %} 

Зарегистрируйте новый шаблон типа формы в config.yml :

 twig: form_themes: - AppBundle::Form/image.html.twig 

Создайте новый тип формы и сохраните его как ImageType.php (полный путь: src/AppBundle/Form/Type/ImageType.php ):

 <?php namespace AppBundle\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Form\FormView; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormBuilderInterface; /** * Class ImageType * * @package AppBundle\Form\Type */ class ImageType extends AbstractType { /** * @return string */ public function getParent() { return 'file'; } /** * @return string */ public function getName() { return 'image'; } /** * @param OptionsResolver $resolver */ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'image_web_path' => '' )); } /** * @param FormView $view * @param FormInterface $form * @param array $options */ public function buildView(FormView $view, FormInterface $form, array $options) { $view->vars['image_web_path'] = $options['image_web_path']; } /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->setAttribute('image_web_path', $options['image_web_path']) ; } } 

Если вы это сделали. Вы можете просто импортировать новый ImageType в класс администратора сущности:

 use AppBundle\Form\Type\ImageType 

И затем, наконец, используйте новый тип формы без какого-либо встроенного html-кода или кода шаблона в configureFormFields :

 $formMapper ->add('imageFile', ImageType::class, ['image_web_path' => $image->getImagePath()]) ; 

Вместо $image->getImagePath() вы должны вызвать свой собственный метод, который возвращает URL-адрес вашему изображению.

Скриншоты

Создание нового объекта изображения с помощью sonata admin:

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

Редактирование объекта изображения с помощью sonata admin:

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

Вы можете просто сделать это

  $image = $this->getSubject(); $imageSmall = ''; if($image){ $container = $this->getConfigurationPool()->getContainer(); $media = $container->get('sonata.media.twig.extension'); $format = 'small'; if($webPath = $image->getImageSmall()){ $imageSmall = '<img src="'.$media->path($image->getImageSmall(), $format).'" class="admin-preview" />'; } } $formMapper->add('imageSmall', 'sonata_media_type', array( 'provider' => 'sonata.media.provider.image', 'context' => 'default', 'help' => $imageSmall )); 

Teo.sk написал метод показа изображений с помощью VichUploader. Я нашел вариант, который позволяет показывать изображения без этого пакета.

Сначала нам нужно создать наш form_type. Существует учебное пособие: symfony_tutorial

В главном классе администратора:

 namespace Your\Bundle; //.....// class ApplicationsAdmin extends Admin { //...// public function getFormTheme() { return array_merge( parent::getFormTheme(), array('YourBundle:Form:image_type.html.twig') //your path to form_type template ); protected function configureFormFields(FormMapper $formMapper) { $formMapper->add('file_photo', 'image', array( 'data_class' => 'Symfony\Component\HttpFoundation\File\File', 'label' => 'Photo', 'image_web_path' => $this->getRequest()->getBasePath().'/'.$subject->getWebPathPhoto()// it's a my name of common getWebPath method )) //....// ; } } 

Следующая часть – это код из класса ImageType.

 namespace Your\Bundle\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\OptionsResolver\OptionsResolverInterface; use Symfony\Component\OptionsResolver\Options; use Symfony\Component\Form\FormView; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormBuilder; use Symfony\Component\Form\FormBuilderInterface; class ImageType extends AbstractType { public function getParent() { return 'file'; } public function getName() { return 'image'; } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'image_web_path' => '' )); } public function buildView(FormView $view, FormInterface $form, array $options) { $view->vars['image_web_path'] = $options['image_web_path']; } public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->setAttribute('image_web_path', $options['image_web_path']) ; } } 

И в конце времени для шаблона twig_type.

 {% block image_widget %} {% spaceless %} {% set type = type|default('file') %} <input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/> <img src="{{ image_web_path }}" alt="image_photo"/> {% endspaceless %} {% endblock %} 

Для меня это работает! Я также использую лавинный пакет для изменения размеров изображений.

Существует простой способ – но вы увидите изображение под кнопкой загрузки. SonataAdmin позволяет помещать необработанный HTML в параметр «help» для любого поля данной формы. Вы можете использовать эту функцию для вставки тега изображения:

 protected function configureFormFields(FormMapper $formMapper) { $object = $this->getSubject(); $container = $this->getConfigurationPool()->getContainer(); $fullPath = $container->get('request')->getBasePath().'/'.$object->getWebPath(); $formMapper->add('file', 'file', array('help' => is_file($object->getAbsolutePath() . $object->getPlanPath()) ? '<img src="' . $fullPath . $object->getPlanPath() . '" class="admin-preview" />' : 'Picture is not avialable') }