How to display the current picture above the upload field in SonataAdminBundle?
Solution 1
You can easily do this on show page
by template attribute pass on $showmapper
->add('picture', NULL, array(
'template' => 'MyProjectBundle:Project:mytemplate.html.twig'
);
and inside your template you get current object so u can call get method and pull image path
<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>
To show image in edit mode you have to override fileType
or you have to create your own customType on top of fileType
There is also some bundle which is having this kind of functionality check out this GenemuFormBundle
Solution 2
I have managed to put the image above the field in the edit form. But my solution is a little bit specific, because I use Vich Uploader Bundle to handle uploads, so the generation of the image url was a little bit easier thanks to bundle helpers.
Let's look at my example, a film poster field in a film entity. This is part of my admin class:
//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
is handled by a custom field type, that is just a child of file type by setting it's getParent
method: (don't forget to register your type class as a service)
//MyCompany/MyBundle/Form/Type/MyBundleAdminImageType.php
public function getParent()
{
return 'file';
}
Then I have a template that extends Sonata's default styling, and I have it included in the admin class:
//MyCompany/MyBundle/Admin/FilmAdmin.php
public function getFormTheme() {
return array('MyCompanyMyBundle:Form:mycompany_admin_fields.html.twig');
}
And finally I have a block for my custom image type that extends the basic file type:
//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 %}
This causes that a 200px wide preview of image (if exists) is shown above the upload field, linked to it's full size version opening in new tab. You can customize it as you want, e.g. adding a lightbox plugin.
Solution 3
you can easily do this on edit page by helpers(FormMapper->setHelps) or option "help" pass on 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)
;
}
Solution 4
Solution for Symfony3
The answer from @kkochanski is the cleanest way I found so far. Here a version ported to Symfony3. I also fixed some bugs.
Create a new template image.html.twig
for your new form type (full path: 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 %}
Register the new form type template in your config.yml
:
twig:
form_themes:
- AppBundle::Form/image.html.twig
Create a new form type and save it as ImageType.php
(full path: 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'])
;
}
}
If you have done this. You can just import the new ImageType
in your entity admin class:
use AppBundle\Form\Type\ImageType
And then, finally use the new form type without any inline-html or boilerplate code in configureFormFields
:
$formMapper
->add('imageFile', ImageType::class, ['image_web_path' => $image->getImagePath()])
;
Instead of $image->getImagePath()
you have to call your own method that returns the url to your image.
Screenshots
Creating a new image entity using sonata admin:
Editing a image entity using sonata admin:
Solution 5
You can simple do by this way
$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
));
RockTheShow
Code proficient Club & Wedding DJ based in Kent, UK. https://rocktheshow.co.uk
Updated on July 05, 2022Comments
-
RockTheShow almost 2 years
I am using SonataAdminBundle (with Doctrine2 ORM) and I have successfully added a file upload feature to my Picture model.
I would like, on the Show and Edit pages, to display a simple
<img src="{{ picture.url }} alt="{{ picture.title }} />
tag just above the relevant form field (provided that the Picture being edited is not new, of course), so that the user may see the current photo, and decide whether to change it or not.After hours of research, I've been unable to figure out how to do it. I suppose I need to override some template, but I'm a bit lost... Can somebody give me a hint?
Thank you!
Here is the relevant section of my PictureAdmin class.
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 }
-
Steve over 11 yearsThis works for the show page, but is there any way to put the image above the field as per the question?
-
caponica over 10 yearsThis is great when working with the PictureAdmin class but any idea how to make it work when PictureAdmin is embedded in another admin class, e.g. using
$formMapper->add('linkedPicture', 'sonata_type_admin')
fromPageAdmin::configureFormFields()
? -
GBRocks over 10 years@caponica You figured out how to do that...?? I am stuck at the same situation too..
-
caponica over 10 yearsYes, I got it working. It's a while since I looked at the code but you basically have to detect when the field is embedded and then use something like pastebin.com/rvh65viG in your ImageAdmin class
-
Heroes84 almost 7 yearsI have issue with Symfony 3.2: Could not load type "file" 500 Internal Server Error - InvalidArgumentException in vendor/symfony/symfony/src/Symfony/Component/Form/FormRegistry.php at line 87 + at FormRegistry ->getType ('file') in vendor/symfony/symfony/src/Symfony/Component/Form/FormRegistry.php at line 121
-
revengeance almost 6 yearsFast, but dirty. :D