Я использую 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) ; }
Ответ от @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') }