Comment afficher l'image actuelle au-dessus du champ upload dans SonataAdminBundle?
j'utilise SonataAdminBundle (avec Doctrine2 ORM) et j'ai ajouté avec succès une fonctionnalité de téléchargement de fichier à mon modèle D'image.
je voudrais, sur le Afficher et Modifier pages, pour afficher un simple <img src="{{ picture.url }} alt="{{ picture.title }} />
balise juste au-dessus du champ de formulaire pertinent (à condition que l'image en cours d'édition n'est pas Nouvelle, bien sûr), de sorte que l'utilisateur peut voir la photo actuelle, et décider de la changer ou non.
Merci!
<!-Voici la section pertinente de mon cours de 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
}
7 réponses
vous pouvez facilement faire cela sur la page d'exposition
par attribut de modèle passe sur $showmapper
->add('picture', NULL, array(
'template' => 'MyProjectBundle:Project:mytemplate.html.twig'
);
et à l'intérieur de votre modèle vous obtenez l'objet courant ainsi vous pouvez appeler la méthode get et tirer le chemin d'image
<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>
pour afficher l'image en mode édition, vous devez outrepasser fileType
ou vous devez créer votre propre customType en plus de fileType
il y a aussi un paquet qui a ce genre de fonctionnalité découvrez ce GenemuFormBundle
j'ai réussi à mettre l'image au-dessus du champ dans le formulaire d'édition. Mais ma solution est un peu spécifique, car j'utilise Vich Uploader Bundle pour gérer les téléchargements, donc la génération de l'url de l'image a été un peu plus facile grâce aux assistants bundle.
regardons mon exemple, un champ poster de film dans une entité de film. Cela fait partie de mon admin de la classe:
//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
est gérée par un type de champ personnalisé, c'est juste un enfant du type de fichier par paramètre getParent
méthode: (n'oubliez pas d'enregistrer votre type de classe en tant que service)
//MyCompany/MyBundle/Form/Type/MyBundleAdminImageType.php
public function getParent()
{
return 'file';
}
Puis-je avoir un modèle qui s'étend de la Sonata défaut de style, et je l'ai inclus dans l'admin de la classe:
//MyCompany/MyBundle/Admin/FilmAdmin.php
public function getFormTheme() {
return array('MyCompanyMyBundle:Form:mycompany_admin_fields.html.twig');
}
et finalement j'ai un bloc pour mon type d'image personnalisé qui étend le type de fichier de base:
//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 %}
cela provoque qu'une prévisualisation de l'image de 200px (si elle existe) s'affiche au-dessus du champ de téléchargement, liée à son ouverture de la version complète dans la nouvelle onglet. Vous pouvez le personnaliser comme vous le souhaitez, par exemple en ajoutant un plugin lightbox.
Vous pouvez facilement faire ceci sur la page d'édition par les helpers (FormMapper - >setHelps) ou l'option "help" transmettre 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 pour Symfony3
la réponse de @kkochanski est le moyen le plus propre que j'ai trouvé jusqu'à présent. Voici une version portée sur Symfony3. J'ai aussi corrigé quelques bugs.
Créer un nouveau modèle image.html.twig
pour votre nouveau formulaire, tapez (chemin complet: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 %}
enregistrez le nouveau modèle de type de formulaire dans votre config.yml
:
twig:
form_themes:
- AppBundle::Form/image.html.twig
créer un nouveau type de formulaire et le sauvegarder comme ImageType.php
(chemin d'accès complet: 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'])
;
}
}
Si vous avez fait cela. Vous pouvez simplement importer le nouveau ImageType
dans votre classe admin entity:
use AppBundle\Form\Type\ImageType
et enfin, utilisez le nouveau type de formulaire sans code inline-html ou boilerplate dans configureFormFields
:
$formMapper
->add('imageFile', ImageType::class, ['image_web_path' => $image->getImagePath()])
;
au Lieu de $image->getImagePath()
vous devez appeler votre propre méthode qui retourne l'url de votre image.
Screenshots
création d'une nouvelle entité image à l'aide de sonata admin:
éditer une image en utilisant Sonata admin:
Vous pouvez très simplement faire de cette manière
$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 a écrit la méthode de montrer des images en utilisant VichUploader. J'ai trouvé une option qui vous permet de montrer des images sans ce paquet.
nous devons d'abord créer notre form_type. Il est tutoriel: symfony_tutorial
dans la classe Admin principale:
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
))
//....//
;
}
}
la partie suivante est un code de la classe 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'])
;
}
}
et sur l'Heure de fin du modèle de brindille image_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 %}
pour moi ça marche! Je suis également en utilisant avalanche bundle pour redimensionner les images.
Il y a un moyen facile - mais vous verrez l'image au-dessous du bouton de téléchargement. SonataAdmin permet de mettre du HTML brut dans l'option ‘help’ pour n'importe quel champ de formulaire donné. Vous pouvez utiliser cette fonctionnalité pour intégrer une balise image:
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')
}