Cuando usamos SonataAdmin para generar las áreas de administración en nuestros proyectos Symfony, nos encontramos con un problema al trabajar con campos imagen, al no contar con una forma de previsualizarlas o de mostrar su thumbnail, bien sea en un listado o en un formulario. En este artículo vamos a ver distintas opciones que tenemos para conseguir este propósito.
La forma más rápida, en el caso de que queramos mostrar el thumbnail en un formulario, es usando la opción help
:
// Vabadus/MiBundle/Admin/MiClaseAdmin.php
<?php
namespace VabadusMiBundleAdmin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
class MiClaseAdmin extends Admin
{
// ...
protected function configureFormFields(FormMapper $formMapper)
{
$options = array('required' => false);
if (($subject = $this->getSubject()) && $subject->getImagen()){
$path = $subject->getImagenWebPath();
$options['help'] = '<img src="'.$path.'">';
}
$formMapper
// ...
->add('imagenFile', 'file', $options)
// ...
;
}
// ...
}
Otra opción igual de fácil, pero válida tanto en un campo de formulario como en un listado, es usar el atributo template
, en el que se indica la plantilla que tiene que se tiene que usar para mostrar ese campo en particular. Por ejemplo, si quisiéramos mostrar el thumbnail de un campo imagen en un listado, por un lado indicamos la plantilla en el campo correspondiente de nuestra clase Admin y por otro, definimos la plantilla twig que la muestra como nosotros queremos:
// Vabadus/MiBundle/Admin/MiClaseAdmin.php
<?php
namespace Vabadus\MiBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
class MiClaseAdmin extends Admin
{
// ...
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
// ...
->add('imagen', NULL, array(
'template' => 'VabadusBundle:MiClase:plantilla_imagen.html.twig'
)
// ...
;
}
// ...
}
{# Vabadus/MiBundle/Resources/views/MiClase/plantilla_imagen.html.twig #}
<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>
Por último, tenemos la opción más completa y versátil. Lo que haremos será crear nuestro propio tipo de campo que configuramos en nuestra clase Admin, en el campo que corresponda, indicando también en el método getFormTheme
la plantilla que redefine nuestro campo:
// Vabadus/MiBundle/Admin/MiClaseAdmin.php
<?php
namespace Vabadus\MiBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
class MiClaseAdmin extends Admin
{
// ...
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
// ...
->add('imagen', 'mibundle_admin_imagen')
// ...
;
}
// ...
public function getFormTheme() {
return array_merge(
parent::getFormTheme(),
array('VabadusBundle:Form:vabadus_admin_fields.html.twig')
);
}
}
Definimos nuestro nuevo tipo y lo registramos como servicio:
// Vabadus/MiBundle/Form/Type/adminImagenType.php
<?php
namespace Vabadus\MiBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class adminImagenType extends AbstractType
{
public function getParent()
{
return 'file';
}
public function getName()
{
return 'mibundle_admin_imagen';
}
}
# Vabadus/MiBundle/Resources/config/services.yml
vbd.form.type.mibundle_admin_imagen:
class: Vabadus\MiBundle\Form\Type\adminImagenType
tags:
- { name: form.type, alias: mibundle_admin_imagen }
Por último, nos faltaría crear la plantilla correspondiente:
{# Vabadus/MiBundle/Resources/views/Form/vabadus_admin_fields.html.twig #}
{% block mibundle_admin_imagen_widget %}
{% spaceless %}
{% set subject = form.vars.sonata_admin.admin.getSubject %}
{% if subject.path_imagen %}
<img src="{{ asset('uploads/' ~ subject.path_imagen) }}" width="70">
{% endif %}
{% set type = type|default('file') %}
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}"{% endif %}>
{% endspaceless %}
{% endblock %}