Как отобразить текущее изображение над полем загрузки в 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
}
Ответы
Ответ 1
Вы можете легко сделать это на странице показа
по атрибуту шаблона передайте $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
или вам нужно создать собственный собственный тип поверх fileType
Существует также некоторый пакет, который имеет такую функциональность
посмотрите GenemuFormBundle
Ответ 2
Мне удалось поместить изображение над полем в форме редактирования. Но мое решение немного специфично, потому что я использую 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, и я включил его в класс admin:
//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 пикселей, связанный с его открытием версии полного размера на новой вкладке. Вы можете настроить его так, как хотите. добавление плагина лайтбокса.
Ответ 3
вы можете легко сделать это на странице редактирования с помощью помощников (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)
;
}
Ответ 4
Решение для 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
И затем, наконец, используйте новый тип формы без какого-либо inline-html или шаблона кода в configureFormFields
:
$formMapper
->add('imageFile', ImageType::class, ['image_web_path' => $image->getImagePath()])
;
Вместо $image->getImagePath()
вы должны вызвать свой собственный метод, который возвращает URL-адрес вашему изображению.
Скриншоты
Создание нового объекта изображения с помощью администратора сонаты:
![введите описание изображения здесь]()
Редактирование объекта изображения с помощью sonata admin:
![введите описание изображения здесь]()
Ответ 5
Вы можете просто сделать это путем
$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
));
Ответ 6
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 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 %}
Для меня это работает! Я также использую пакет лавин для изменения размеров изображений.
Ответ 7
Существует простой способ - но вы увидите изображение под кнопкой загрузки.
SonataAdmin позволяет помещать необработанный HTML в "help option" для любого поля данной формы. Вы можете использовать эту функцию для вставки тега изображения:
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')
}