<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Twig Archives - fuga_digital</title>
	<atom:link href="https://fugadigital.com/tag/twig/feed/" rel="self" type="application/rss+xml" />
	<link>https://fugadigital.com/tag/twig/</link>
	<description>Naturalmente digital</description>
	<lastBuildDate>Sat, 08 Apr 2017 06:20:24 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>
	<item>
		<title>Agregar campos informativos en formularios de Sonata Admin</title>
		<link>https://fugadigital.com/agregar-campos-informativos-en-formularios-de-sonata-admin/</link>
					<comments>https://fugadigital.com/agregar-campos-informativos-en-formularios-de-sonata-admin/#respond</comments>
		
		<dc:creator><![CDATA[Arturo]]></dc:creator>
		<pubDate>Mon, 12 May 2014 14:45:20 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Sonata]]></category>
		<category><![CDATA[SonataAdminBundle]]></category>
		<category><![CDATA[Symfony2]]></category>
		<category><![CDATA[Twig]]></category>
		<guid isPermaLink="false">http://fugadigital.com/?p=34</guid>

					<description><![CDATA[<p>No es sorpresa la gran popularidad que tiene el bundle Sonata Admin, siendo como dicen ellos «El generador de admistradores faltante en Symfony2» (énfasis mío). Al generar los adminstradores de nuestras entidades es común necesitar desplegar junto con los campos a editar, campos informativos del objeto (fecha de creación, último acceso, autor, etc.). Se puede &#8230; </p>
<p class="link-more"><a href="https://fugadigital.com/agregar-campos-informativos-en-formularios-de-sonata-admin/" class="more-link">Continuar leyendo<span class="screen-reader-text"> "Agregar campos informativos en formularios de Sonata Admin"</span></a></p>
<p>La entrada <a href="https://fugadigital.com/agregar-campos-informativos-en-formularios-de-sonata-admin/">Agregar campos informativos en formularios de Sonata Admin</a> se publicó primero en <a href="https://fugadigital.com">fuga_digital</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>No es sorpresa la gran popularidad que tiene el bundle <em>Sonata Admin</em>, siendo como dicen ellos «El generador de admistradores faltante en Symfony2» (énfasis mío).</p>
<p>Al generar los adminstradores de nuestras entidades es común necesitar desplegar junto con los campos a editar, campos informativos del objeto (fecha de creación, último acceso, autor, etc.). Se puede fácilmente agregar los campos y hacerlos no editables y/o desactivarlos, pero visualmente el resultado no es realmente bueno.</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">// simple but ugly
->add('created', null, array(
    'read_only' => true,
    'disabled' => true,
    'widget' => 'single_text',
    'format' => 'EEE, MMM FF yyyy HH:mm'
))</pre><p></p>
<p>Podemos utilizar CSS para mejorar considerablemente la imagen, sin embargo esto no funciona si queremos desplegar estructuras más complejas.</p>
<p><span id="more-34"></span></p>
<p>Tratándose de <em>Symfony2</em> y <em>SonataAdmin</em> es posible adaptar los administradores generados para nuestro bundle en la medida que necesitemos sin impactar en otras áreas. En esta ocasión lo aprovecharemos para crear etiquetas informativas insertables como campos dentro de los formularios.</p>
<p><a href="https://fugadigital.com/wp-content/uploads/2014/05/labeled_cat.jpg"><img fetchpriority="high" decoding="async" src="https://fugadigital.com/wp-content/uploads/2014/05/labeled_cat-300x224.jpg" alt="label in cat" width="300" height="224" class="aligncenter size-medium wp-image-35" srcset="https://fugadigital.com/wp-content/uploads/2014/05/labeled_cat-300x224.jpg 300w, https://fugadigital.com/wp-content/uploads/2014/05/labeled_cat.jpg 500w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Probado con:<br />
Symfony 2.4<br />
Sonata Admin Bundle 2.2</p>
<p>Dependiendo de los objetivos, lo que hacer es:<br />
&#8211; <a href="#type-class">Crear la clase para el nuevo tipo de despliegue</a><br />
&#8211; <a href="#transformer">Crear un transformador para hacer desplegable el objeto</a><br />
&#8211; <a href="#admin-config">Configurar las clases de administración con el objeto y el nuevo tipo</a><br />
&#8211; <a href="#twig">Crear los bloques en Twig con el marcado para el despliegue</a></p>
<p>Lo siguiente mostrará como desplegar un objecto DateTime, pero la guía es fácilmente adaptable para otros tipos, como números, hipervínculos, entidades, colecciones o cualquier cosa.</p>
<h3 id="type-class">Crear la clase para el nuevo tipo de despliegue</h3>
<p>Primero necesitamos crear una clase para el nuevo tipo</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">/* Acme/DemoBundle/Form/StaticTextType.php */
<?php

namespace Acme\DemoBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class StaticTextType extends AbstractType
{
    public function getParent()
    {
        return 'text';
    }

    public function getName()
    {
        return 'acme_static_text';
    }
}</pre><p></p>
<p>Para usar el nuevo tipo podemos incluir la clase e instanciarla en el administrador</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Acme/DemoBundle/Admin/EntityAdmin.php */
<?php
namespace Acme\DemoBundle\Admin;

...
use Acme\DemoBundle\Form\StaticTextType;
... 

...
    ->add('id', new StaticTextType())
...</pre><p></p>
<p>o crear crear un servicio y registrarlo como nuevo tipo de formulario. Esto también permite hacer uso de él a través de su etiqueta.</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag"># Acme/DemoBundle/Resources/config/services.yml
services:
    ...
    acme_demo.form.type.info:
        class: Acme\DemoBundle\Form\StaticTextType
        tags:
            - { name: form.type, alias: acme_static_text }</pre><p></p><pre class="urvanov-syntax-highlighter-plain-tag">/* Acme/DemoBundle/Admin/EntityAdmin.php */
    ...
    ->add('id', 'acme_static_text')</pre><p></p>
<p>Para desplegar información básica como números o cadenas no necesitamos crear el transformador pues nuestro tipo hereda las características del tipo &#8216;text&#8217;.</p>
<h3 id="transformer">Crear un transformador para hacer desplegable el objeto</h3>
<p>Para desplegar la fecha y hora necesitamos un transformador que genere la cadena que represente a la instancia <code>DateTime</code>.</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">/* Acme/DemoBundle/Form/DataTransformer/DateTimeToStringTransformer.php */
<?php
namespace Acme\DemoBundle\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;

class DateTimeToStringTransformer implements DataTransformerInterface
{
    /**
     * The format for our DateTime object
     * @var string
     */
    private $format;
    
    public function __construct($format)
    {
        $this->format = $format;
    }
    
    /**
     * Transforms a datetime object to a string.
     *
     * @param  DateTime|null $date
     * @return string
     */
    public function transform($dateTime)
    {
        return null === $dateTime
	    ? return ''
	    : $dateTime->format($this->format);
    }

    /**
     * Transforms a string date to a DateTime object.
     *
     * @param  string $dateTime
     *
     * @return DateTime|null
     *
     * @throws TransformationFailedException if cannot transform to DateTime.
     */
    public function reverseTransform($dateTime)
    {
        if (empty($dateTime)) {
            return null;
        }

        $dt = DateTime::createFromFormat($this->format, $dateTime);
        if (null === $dt) {
            throw new TransformationFailedException(sprintf(
                "Unable to transform '%s' to a DateTime object",
                $dateTime
            ));
        }

        return $dt;
    }
}</pre><p></p>
<h3 id="admin-config">Configurar las clases de administración con el objeto y el nuevo tipo</h3>
<p>Para mostrar los datos de los campos de manera que no sean procesados por el formulario, podemos agregar el campo configurándolo como no mapeado y el dato manualmente agregado o configurarlo como desactivado.</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag"><?php
    // correct display, error on save
    ->add('id', 'acme_static_text', array(
        'required' => false
    ))

    // correct display, ignored on save
    ->add('id', 'acme_static_text', array(
        'required' => false,
        'disabled' => true,
    ))

    $entity = $this->getSubject();
    ->add('id', 'acme_static_text', array(
        'required' => false,
        'mapped' => false,
        'data' => $entity->getId(),
    ))</pre><p></p>
<p>Tip: Como el método <code>$this->getSubject()</code> de la clase de administración regresa la entidad que se está gestionando, tambíen se puede aprovechar para desplegar diferentes campos dependiendo de si se está creando una nueva instancia o editando una existente.</p>
<p>Nota: Al utilizar subadminstradores <code>getSubject()</code> regresa siempre la primera entidad.</p>
<p>Para usar el transformador al estructurar nuestro formulario en el administrador no agregamos directamente nuestro objeto con el tipo, sino que creamos un objeto <code>FormBuilder</code> al que le agregaremos una instancia del transformador.</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">/* Acme/DemoBundle/Admin/EntityAdmin.php */
<?php
    namespace Acme\DemoBundle\Admin;

    ...
    use Acme\DemoBundle\Form\DataTransformer\DateTimeToStringTransformer;
    ...

        // Static text showing the DateTime object
        ->add(
            $formMapper->create('created', 'acme_static_text', array(
                // data_class set to null to avoid object type errors
                'data_class' => null,
                'required' => false,
                'disablex' => true,
            ))
            ->addViewTransformer(new DateTimeToStringTransformer('D, M d Y H:i:s'))
        )</pre><p></p>
<p>Algunos otros ejemplos de configuración:</p><pre class="urvanov-syntax-highlighter-plain-tag">// 1-to-N collection would be something like this
        ->add('pages', 'acme_static_text_collection', array(
            'label' => false,
            'type' => 'entity',
                'options' => array(
                'class' => 'AcmeDemoBundle:Foo',
            ),
        ))

        // An entity would look like
        ->add(
            $formMapper->create('author', 'info', array(
                'data_class' => null,
                'required' => false,
                'mapped' => false,
                'data' => $subject->getAuthor(),
                'property_path' => null
            ))
            ->addViewTransformer(new UserToStringTransformer())
        )</pre><p></p>
<h3 id="twig">Crear los bloques en Twig con el marcado para el despliegue</h3>
<p>Finalmente vamos a construir los widgets con el HTML para mostrar la información. Como nuestro tipo se llama <em>acme_static_text</em> el bloque lo debemos crear con el nombre <em>acme_static_text_widget</em>.</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">{# Acme/DemoBundle/Resources/views/Form/widgets.html.twig #}
{% block acme_static_text_widget %}
    {% spaceless %}
        <div class="sonata-ba-field sonata-ba-field-standard-natural">{{ value }}</div>
    {% endspaceless %}
{% endblock %}</pre><p></p>
<p>Ahora debemos agregar nuestra plantilla con widgets en el administrador para que pueda ser usada. Una manera sencilla es sobrecargando el método <code>getFormTheme()</code> de nuestra clase de administración.</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">/* Acme/DemoBundle/Admin/EntityAdmin.php */
<?php
namespace Allegro\SitesBundle\Admin;

...
use Allegro\SitesBundle\Form\DataTransformer\DateTimeToStringTransformer;
...

class EntityAdmin extends Admin
{
    /**
     * Adds a custom collection template.
     * @return array
     */
    public function getFormTheme()
    {
        return array_merge(
            parent::getFormTheme(),
            array('AcmeDemoBundle:Form:widgets.html.twig')
        );
    }</pre><p></p>
<p>Y con esto terminamos. Si bien la implementación no es tan rápida, no es compleja y es valiosa porque muestra una manera para personalizar cualquier campo en los administradores de nuestros bundles.</p>
<p>La entrada <a href="https://fugadigital.com/agregar-campos-informativos-en-formularios-de-sonata-admin/">Agregar campos informativos en formularios de Sonata Admin</a> se publicó primero en <a href="https://fugadigital.com">fuga_digital</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://fugadigital.com/agregar-campos-informativos-en-formularios-de-sonata-admin/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
