cómo domar sonataadminbundle

246

Upload: victoria-quirante-ruiz

Post on 08-Jan-2017

715 views

Category:

Software


1 download

TRANSCRIPT

Page 1: Cómo domar SonataAdminBundle
Page 2: Cómo domar SonataAdminBundle
Page 3: Cómo domar SonataAdminBundle

Trabajo en Limenius

Hacemos proyectos a medida en Symfony y React

Raro es el proyecto que no requiera un panel de administración

Desde hace bastante resolvemos esa parte con SonataAdminBundle

Victoria Quirante@vicqr

[email protected]

Page 4: Cómo domar SonataAdminBundle

I. Introducción

O acerca de por qué y para qué estamos aquí

Page 5: Cómo domar SonataAdminBundle

El creador

Page 6: Cómo domar SonataAdminBundle

Principales colaboradores

Page 7: Cómo domar SonataAdminBundle
Page 8: Cómo domar SonataAdminBundle

Principales problemas históricamente atribuidos

- Difícil de instalar

Page 9: Cómo domar SonataAdminBundle

Principales problemas históricamente atribuidos

- Difícil de instalar- Feo

Page 10: Cómo domar SonataAdminBundle

Principales problemas históricamente atribuidos

- Difícil de instalar- Feo- Mala documentación

Page 11: Cómo domar SonataAdminBundle

Principales problemas históricamente atribuidos

- Difícil de instalar- Feo- Mala documentación- Mucho código, difícil de investigar

Page 12: Cómo domar SonataAdminBundle

Principales problemas históricamente atribuidos

- Difícil de instalar- Feo- Mala documentación- Mucho código, difícil de investigar

Page 13: Cómo domar SonataAdminBundle

Principales problemas históricamente atribuidos

- Difícil de instalar- Feo- Mala documentación- Mucho código, difícil de investigar

Page 14: Cómo domar SonataAdminBundle

Principales problemas históricamente atribuidos

- Difícil de instalar- Feo- Mala documentación regular- Mucho código, difícil de investigar

Page 15: Cómo domar SonataAdminBundle

Principales problemas históricamente atribuidos

- Difícil de instalar- Feo- Mala documentación regular- Mucho código, difícil de investigar

Page 16: Cómo domar SonataAdminBundle

El problema que queremos resolver...

Page 17: Cómo domar SonataAdminBundle

...es implementar un panel de administración

Page 18: Cómo domar SonataAdminBundle

Lo que es y lo que no es Sonata

No es el David de Miguel Ángel

Ni la teoría de cuerdas

Ni el número áureo

Page 19: Cómo domar SonataAdminBundle

Lo que es y lo que no es Sonata

No es el David de Miguel Ángel

Ni la teoría de cuerdas

Ni el número áureo

Pero sí es algo muy útil

Page 20: Cómo domar SonataAdminBundle

Lo que es y lo que no es Sonata

No es el David de Miguel Ángel

Ni la teoría de cuerdas

Ni el número áureo

Pero sí es algo muy útilComo Symfony, como PHP

Page 21: Cómo domar SonataAdminBundle

Charla práctica

- No es una revisión exhaustiva de la documentación- Vamos a mostrar cómo se usa en la práctica- Cuál es el recorrido desde la instalación limpia

Page 22: Cómo domar SonataAdminBundle

Charla práctica

- No es una revisión exhaustiva de la documentación- Vamos a mostrar cómo se usa en la práctica- Cuál es el recorrido desde la instalación limpia

1) Qué te da Sonata “gratis”2) Cómo personalizo lo que quiera a partir de ahí

Page 23: Cómo domar SonataAdminBundle

Dos tipos de desarrolladores

Page 24: Cómo domar SonataAdminBundle
Page 25: Cómo domar SonataAdminBundle
Page 26: Cómo domar SonataAdminBundle

Charla práctica

https://github.com/VictoriaQ/sonatademo

Page 27: Cómo domar SonataAdminBundle

II. El Admin básico

O cómo sacar provecho del sudor de otros de forma que llega a dar hasta un poco de vergüenza

Page 28: Cómo domar SonataAdminBundle

Screenshots (II): Instalación limpia

Page 29: Cómo domar SonataAdminBundle

Screenshots (II): Instalación limpia

Page 30: Cómo domar SonataAdminBundle

Screenshots (II): Instalación limpia

Page 31: Cómo domar SonataAdminBundle

¿Cómo empezamos?

Page 32: Cómo domar SonataAdminBundle

El Admin básico: 3 pasos, 2 minutos

Tenemos la entidad Regalo para la que queremos crear un Admin

Page 33: Cómo domar SonataAdminBundle

El Admin básico: 3 pasos, 2 minutos

Tenemos la entidad Regalo para la que queremos crear un Admin:

1) Creamos la clase RegaloAdmin2) Registramos el servicio

Page 34: Cómo domar SonataAdminBundle

El Admin básico - Paso 1: Creamos la clase Admin

# src/AppBundle/Admin/RegaloAdmin.php

class RegaloAdmin extends Admin

{

protected function configureFormFields(FormMapper $formMapper)

{

$formMapper->add('nombre');

}

protected function configureDatagridFilters(DatagridMapper

$datagridMapper)

{

$datagridMapper->add('nombre');

}

protected function configureListFields(ListMapper $listMapper)

{

$listMapper->addIdentifier('nombre');

}

}

Page 35: Cómo domar SonataAdminBundle

El Admin básico - Paso 1: Creamos la clase Admin

# src/AppBundle/Admin/RegaloAdmin.php

class RegaloAdmin extends Admin

{

protected function configureFormFields(FormMapper $formMapper)

{

$formMapper->add('nombre');

}

protected function configureDatagridFilters(DatagridMapper

$datagridMapper)

{

$datagridMapper->add('nombre');

}

protected function configureListFields(ListMapper $listMapper)

{

$listMapper->addIdentifier('nombre');

}

}

Page 36: Cómo domar SonataAdminBundle

El Admin básico - Paso 1: Creamos la clase Admin

# src/AppBundle/Admin/RegaloAdmin.php

class RegaloAdmin extends Admin

{

protected function configureFormFields(FormMapper $formMapper)

{

$formMapper->add('nombre');

}

protected function configureDatagridFilters(DatagridMapper

$datagridMapper)

{

$datagridMapper->add('nombre');

}

protected function configureListFields(ListMapper $listMapper)

{

$listMapper->addIdentifier('nombre');

}

}

Page 37: Cómo domar SonataAdminBundle

El Admin básico - Paso 1: Creamos la clase Admin

# src/AppBundle/Admin/RegaloAdmin.php

class RegaloAdmin extends Admin

{

protected function configureFormFields(FormMapper $formMapper)

{

$formMapper->add('nombre');

}

protected function configureDatagridFilters(DatagridMapper

$datagridMapper)

{

$datagridMapper->add('nombre');

}

protected function configureListFields(ListMapper $listMapper)

{

$listMapper->addIdentifier('nombre');

}

}

Page 38: Cómo domar SonataAdminBundle

El Admin básico - Paso 1: Creamos la clase Admin

# src/AppBundle/Admin/RegaloAdmin.php

class RegaloAdmin extends Admin

{

protected function configureFormFields(FormMapper $formMapper)

{

$formMapper->add('nombre');

}

protected function configureDatagridFilters(DatagridMapper

$datagridMapper)

{

$datagridMapper->add('nombre');

}

protected function configureListFields(ListMapper $listMapper)

{

$listMapper->addIdentifier('nombre');

}

}

Page 39: Cómo domar SonataAdminBundle

El Admin básico - Paso 2: Registramos el servicio

# app/config/services.yml

services: admin.regalo: class: AppBundle\Admin\RegaloAdmin arguments: [~, AppBundle\Entity\Regalo, ~] tags: - { name: sonata.admin, manager_type: orm, label: Regalos }

Page 40: Cómo domar SonataAdminBundle

El Admin básico - Paso 2: Registramos el servicio

# app/config/services.yml

services: admin.regalo: class: AppBundle\Admin\RegaloAdmin arguments: [~, AppBundle\Entity\Regalo, ~] tags: - { name: sonata.admin, manager_type: orm, label: Regalos }

Page 41: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin

Page 42: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin

Page 43: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin

Page 44: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin

Page 45: Cómo domar SonataAdminBundle

El Admin básico - Paso 3 (opcional): Menú lateral

# app/config/config.yml

sonata_admin: dashboard: groups: demo.admin.main: label: Admin label_catalogue: AppBundle icon: '<i class="fa fa-database"></i>' items: - admin.regalo

Page 46: Cómo domar SonataAdminBundle

El Admin básico - Paso 3 (opcional): Menú lateral

# app/config/config.yml

sonata_admin: dashboard: groups: demo.admin.main: label: Admin label_catalogue: AppBundle icon: '<i class="fa fa-database"></i>' items: - admin.regalo

Page 47: Cómo domar SonataAdminBundle

El Admin básico - Paso 3 (opcional): Menú lateral

# app/config/config.yml

sonata_admin: dashboard: groups: demo.admin.main: label: Admin label_catalogue: AppBundle icon: '<i class="fa fa-database"></i>' items: - admin.regalo

Page 48: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin (ítem en menú lateral)

Page 49: Cómo domar SonataAdminBundle

Ok, ¿y con eso que tengo?

Page 50: Cómo domar SonataAdminBundle

¿Y con eso qué tengo?

- Create, edit, delete...

Page 51: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - El formulario

Page 52: Cómo domar SonataAdminBundle

Lo que Sonata te da hecho

- Create, edit, delete...- Listado paginado, ordenable, filtrable

y exportable

Page 53: Cómo domar SonataAdminBundle

Lo que Sonata te da hecho

- Create, edit, delete...

- Listado paginado, ordenable, filtrable y exportable

Page 54: Cómo domar SonataAdminBundle
Page 55: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - El listado

Page 56: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - El listado

Page 57: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - Los filtros

Page 58: Cómo domar SonataAdminBundle

Configuración básica del listado

Page 59: Cómo domar SonataAdminBundle

Configuración básica del listado

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureListFields(ListMapper $listMapper) { $listMapper ->add('nombre')

; }

Page 60: Cómo domar SonataAdminBundle

Configuración básica del listado

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureListFields(ListMapper $listMapper) { $listMapper ->add('nombre') ->add('precio') ->add('descripcion') ->add('destinatario') ->add('comprador') ; }

Page 61: Cómo domar SonataAdminBundle

Configuración básica del listado

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureListFields(ListMapper $listMapper) { $listMapper ->addIdentifier('nombre') ->add('precio') ->add('descripcion') ->add('destinatario') ->add('comprador') ; }

Page 62: Cómo domar SonataAdminBundle

Configuración básica del listado

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureListFields(ListMapper $listMapper) { $listMapper ->addIdentifier('nombre') ->add('precio', 'currency', array('currency' => 'EUR')) ->add('descripcion') ->add('destinatario') ->add('comprador') ; }

Page 63: Cómo domar SonataAdminBundle

Configuración básica del listado

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureListFields(ListMapper $listMapper) { $listMapper ->addIdentifier('nombre') ->add('precio', 'currency', array('currency' => 'EUR')) ->add('descripcion', null, array('label' => 'Descripción')) ->add('destinatario') ->add('comprador') ; }

Page 64: Cómo domar SonataAdminBundle

Configuración básica del listado

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureListFields(ListMapper $listMapper) { $listMapper ->addIdentifier('nombre') ->add('precio', 'currency', array('currency' => 'EUR')) ->add('descripcion', null, array('label' => 'Descripción')) ->add('destinatario', null, array('editable' => true) ->add('comprador') ; }

Page 65: Cómo domar SonataAdminBundle

Configuración básica del listado

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureListFields(ListMapper $listMapper) { $listMapper ->addIdentifier('nombre') ->add('precio', 'currency', array('currency' => 'EUR')) ->add('descripcion', null, array('label' => 'Descripción')) ->add('destinatario', null, array('editable' => true)) ->add('comprador') ; }

https://sonata-project.org/bundles/admin/3-x/doc/reference/field_types.html

Page 66: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - El listado

Page 67: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - El listado

Page 68: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - El listado

Page 69: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - El listado

Page 70: Cómo domar SonataAdminBundle

Configuración básica del listado

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureListFields(ListMapper $listMapper) { $listMapper

... ->add('_action', null, array( 'actions' => array( 'show' => array(), 'edit' => array(), 'delete' => array(), ) )) ; }

Page 71: Cómo domar SonataAdminBundle

Configuración básica del listado

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureListFields(ListMapper $listMapper) { $listMapper

... ->add('_action', null, array( 'actions' => array( 'show' => array(), 'edit' => array(), 'delete' => array(), ) )) ; }

Page 72: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - El listado

Page 73: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - El listado

Page 74: Cómo domar SonataAdminBundle

Configuración básica del formulario

Page 75: Cómo domar SonataAdminBundle

Configuración básica del formulario

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureFormFields(FormMapper $formMapper) { $formMapper ->add('nombre') ; }

Page 76: Cómo domar SonataAdminBundle

Configuración básica del formulario

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureFormFields(FormMapper $formMapper) { $formMapper ->add('nombre') ->add('precio') ->add('descripcion') ->add('destinatario') ->add('comprador') ; }

Page 77: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - El formulario

Page 78: Cómo domar SonataAdminBundle

Configuración básica del formulario

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureFormFields(FormMapper $formMapper) { $formMapper ->add('nombre') ->add('precio') ->add('descripcion') ->add('destinatario') ->add('comprador') ; }

Page 79: Cómo domar SonataAdminBundle

Configuración básica del formulario

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureFormFields(FormMapper $formMapper) { $formMapper ->with('Regalo', array('class' => 'col-md-6')) ->add('nombre') ->add('precio') ->add('descripcion') ->end() ->with('Participantes', array('class' => 'col-md-6')) ->add('destinatario') ->add('comprador') ->end() ; }

Page 80: Cómo domar SonataAdminBundle

Configuración básica del formulario

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureFormFields(FormMapper $formMapper) { $formMapper ->with('Regalo', array('class' => 'col-md-6')) ->add('nombre') ->add('precio') ->add('descripcion') ->end() ->with('Participantes', array('class' => 'col-md-6')) ->add('destinatario') ->add('comprador') ->end() ; }

Page 81: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - El formulario

Page 82: Cómo domar SonataAdminBundle

Configuración básica del formulario

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureFormFields(FormMapper $formMapper) { $formMapper ->tab('Tab 1') ->with('Regalo', array('class' => 'col-md-6')) ->add('nombre') ->add('precio') ->add('descripcion') ->end() ->with('Participantes', array('class' => 'col-md-6')) ->add('destinatario') ->add('comprador') ->end() ->end() ->tab('Tab 2') ->end() ; }

Page 83: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - El formulario

Page 84: Cómo domar SonataAdminBundle

¿Y si alguno de los campos tiene una relación con otra entidad?

Page 85: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - El formulario

Page 86: Cómo domar SonataAdminBundle

Configuración básica del formulario

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureFormFields(FormMapper $formMapper) { $formMapper

... ->with('Participantes', array('class' => 'col-md-6')) ->add('destinatario') ->add('comprador') ->end() ; }

Page 87: Cómo domar SonataAdminBundle

Configuración básica del formulario

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureFormFields(FormMapper $formMapper) { $formMapper

... ->with('Participantes', array('class' => 'col-md-6')) ->add('destinatario', null) ->add('comprador', null) ->end() ; }

Page 88: Cómo domar SonataAdminBundle

Configuración básica del formulario

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureFormFields(FormMapper $formMapper) { $formMapper

... ->with('Participantes', array('class' => 'col-md-6')) ->add('destinatario', 'entity', array( 'class' => 'AppBundle\Entity\Destinatario')) ->add('comprador', 'entity', array( 'class' => 'AppBundle\Entity\Comprador')) ->end() ; }

Page 89: Cómo domar SonataAdminBundle

Configuración básica del formulario

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureFormFields(FormMapper $formMapper) { $formMapper

... ->with('Participantes', array('class' => 'col-md-6')) ->add('destinatario', null, array( 'class' => 'AppBundle\Entity\Destinatario', 'choice_label' => 'apellidos')) ->add('comprador', null, array( 'class' => 'AppBundle\Entity\Comprador', 'choice_label' => 'apellidos')) ->end() ; }

Page 90: Cómo domar SonataAdminBundle

Configuración básica del formulario

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureFormFields(FormMapper $formMapper) { $formMapper

... ->with('Participantes', array('class' => 'col-md-6')) ->add('destinatario', null, array( 'class' => 'AppBundle\Entity\Destinatario', 'choice_label' => 'nombreCompleto')) ->add('comprador', null, array( 'class' => 'AppBundle\Entity\Comprador', 'choice_label' => 'nombreCompleto')) ->end() ; }

Page 91: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - El formulario

Page 92: Cómo domar SonataAdminBundle

¿Y los one-to-many y many-to-many?

Page 93: Cómo domar SonataAdminBundle

Una collection en el form (one-to-many)

# src/AppBundle/Admin/CompradorAdmin.php

protected function configureFormFields(FormMapper $formMapper) { $formMapper ->with('Datos personales', array('class' => 'col-md-6')) ->add('nombre') ->add('apellidos') ->end()

; }

Page 94: Cómo domar SonataAdminBundle

Una collection en el form (one-to-many)

# src/AppBundle/Admin/CompradorAdmin.php

protected function configureFormFields(FormMapper $formMapper) { $formMapper ->with('Datos personales', array('class' => 'col-md-6')) ->add('nombre') ->add('apellidos') ->end() ->with('Pagos', array('class' => 'col-md-6')) ->add('pagos', 'sonata_type_collection', array( ), array( 'edit' => 'inline', 'inline' => 'table', )) ->end() ; }

Page 95: Cómo domar SonataAdminBundle

Una collection en el form (one-to-many)

# src/AppBundle/Admin/CompradorAdmin.php

protected function configureFormFields(FormMapper $formMapper) { $formMapper ->with('Datos personales', array('class' => 'col-md-6')) ->add('nombre') ->add('apellidos') ->end() ->with('Pagos', array('class' => 'col-md-6')) ->add('pagos', 'sonata_type_collection', array( ), array( 'edit' => 'inline', 'inline' => 'table', )) ->end() ; }

Page 96: Cómo domar SonataAdminBundle

Una collection en el form (one-to-many)

# src/AppBundle/Admin/CompradorAdmin.php

protected function configureFormFields(FormMapper $formMapper) { $formMapper ->with('Datos personales', array('class' => 'col-md-6')) ->add('nombre') ->add('apellidos') ->end() ->with('Pagos', array('class' => 'col-md-6')) ->add('pagos', 'sonata_type_collection', array( ), array( 'edit' => 'inline', 'inline' => 'table', )) ->end() ; }

Y creamos un Admin para la entidad Pago

Page 97: Cómo domar SonataAdminBundle

Una collection en el form (one-to-many)

Page 98: Cómo domar SonataAdminBundle

Una collection en el form (one-to-many)

Page 99: Cómo domar SonataAdminBundle

Una collection en el form (one-to-many)

Page 100: Cómo domar SonataAdminBundle

Una many-to-many en el form

Page 101: Cómo domar SonataAdminBundle

Una many-to-many en el form

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureFormFields(FormMapper $formMapper)

{

$formMapper

...

->with('Establecimientos', array('class' => 'col-md-6'))

->add('tiendas', 'sonata_type_model', array(

'by_reference' => false,

'expanded' => true,

'multiple' => true,

'label' => 'Tiendas')

)

->end()

;

}

Page 102: Cómo domar SonataAdminBundle

Una many-to-many en el form

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureFormFields(FormMapper $formMapper)

{

$formMapper

...

->with('Establecimientos', array('class' => 'col-md-6'))

->add('tiendas', 'sonata_type_model', array(

'by_reference' => false,

'expanded' => true,

'multiple' => true,

'label' => 'Tiendas')

)

->end()

;

}

Page 103: Cómo domar SonataAdminBundle

Una many-to-many en el form

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureFormFields(FormMapper $formMapper)

{

$formMapper

...

->with('Establecimientos', array('class' => 'col-md-6'))

->add('tiendas', 'sonata_type_model', array(

'by_reference' => false,

'expanded' => true,

'multiple' => true,

'label' => 'Tiendas')

)

->end()

;

}

Page 104: Cómo domar SonataAdminBundle

Una many-to-many en el form

Page 105: Cómo domar SonataAdminBundle

Una many-to-many en el form

Page 106: Cómo domar SonataAdminBundle

Una many-to-many en el form

Page 107: Cómo domar SonataAdminBundle

Configuración básica de los filtros

Page 108: Cómo domar SonataAdminBundle

Configuración básica de los filtros

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureDatagridFilters(DatagridMapper $datagridMapper) { $datagridMapper ->add('nombre') ; }

Page 109: Cómo domar SonataAdminBundle

Configuración básica de los filtros

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureDatagridFilters(DatagridMapper $datagridMapper) { $datagridMapper ->add('nombre') ->add('precio') ->add('destinatario', null, array(), 'entity', array( 'class' => 'AppBundle\Entity\Destinatario', 'choice_label' => 'nombreCompleto')) ; }

Page 110: Cómo domar SonataAdminBundle

Screenshots (II): Primer Admin - Los filtros

Page 111: Cómo domar SonataAdminBundle

Hasta aquí lo “gratis”

Page 112: Cómo domar SonataAdminBundle

¿Tenemos mucho o poco?

- Con muy poco esfuerzo tienes muchísimo

- De hecho tienes la mayor parte de lo que necesitas

- Pero el mundo no es perfecto, y vas a necesitar algunas otras cosas en tu panel casi con seguridad

Page 113: Cómo domar SonataAdminBundle
Page 114: Cómo domar SonataAdminBundle

¿Y si quiero...

… tener un formulario maquetado de otra forma?… meter algo “extraño” en un campo del listado?… crear una sección del menú que no sea un listado?… meter algo dentro de Sonata que no tenga nada que ver con el panel de administración…?

Page 115: Cómo domar SonataAdminBundle

¿Y si quiero...

… tener un formulario maquetado de otra forma?… meter algo “extraño” en un campo del listado?… crear una sección del menú que no sea un listado?… meter algo dentro de Sonata que no tenga nada que ver con el panel de administración…?

¿Cuánto me va a costar todo eso? ¿No será mejor empezar de cero?

Page 116: Cómo domar SonataAdminBundle
Page 117: Cómo domar SonataAdminBundle

III. Personalizando

O cómo campar a mis anchas paso a paso

Page 118: Cómo domar SonataAdminBundle

Personalizando

● Templates

● Queries

● Actions

Page 119: Cómo domar SonataAdminBundle

Sobrescribiendo templates

Page 120: Cómo domar SonataAdminBundle

Sobrescribir templates

# app/config/config.yml

sonata_admin: templates: user_block: 'SonataAdminBundle:Core:user_block.html.twig' add_block: 'SonataAdminBundle:Core:add_block.html.twig' layout: 'SonataAdminBundle::standard_layout.html.twig' ajax: 'SonataAdminBundle::ajax_layout.html.twig' dashboard: 'SonataAdminBundle:Core:dashboard.html.twig' search: 'SonataAdminBundle:Core:search.html.twig' list: 'SonataAdminBundle:CRUD:list.html.twig' show: 'SonataAdminBundle:CRUD:show.html.twig' show_compare: 'SonataAdminBundle:CRUD:show_compare.html.twig' edit: 'SonataAdminBundle:CRUD:edit.html.twig'

...

Page 121: Cómo domar SonataAdminBundle

Sobrescribir templates

# app/config/config.yml

sonata_admin: templates: user_block: 'SonataAdminBundle:Core:user_block.html.twig' add_block: 'SonataAdminBundle:Core:add_block.html.twig' layout: 'SonataAdminBundle::standard_layout.html.twig' ajax: 'SonataAdminBundle::ajax_layout.html.twig' dashboard: 'SonataAdminBundle:Core:dashboard.html.twig' search: 'SonataAdminBundle:Core:search.html.twig' list: 'SonataAdminBundle:CRUD:list.html.twig' show: 'SonataAdminBundle:CRUD:show.html.twig' show_compare: 'SonataAdminBundle:CRUD:show_compare.html.twig' edit: 'SonataAdminBundle:CRUD:edit.html.twig'

...

https://sonata-project.org/bundles/admin/3-x/doc/reference/templates.html

Page 122: Cómo domar SonataAdminBundle

Sobrescribir templates

# app/config/config.yml

sonata_admin: templates: user_block: 'SonataAdminBundle:Core:user_block.html.twig' add_block: 'SonataAdminBundle:Core:add_block.html.twig' layout: 'SonataAdminBundle::standard_layout.html.twig' ajax: 'SonataAdminBundle::ajax_layout.html.twig' dashboard: 'SonataAdminBundle:Core:dashboard.html.twig' search: 'SonataAdminBundle:Core:search.html.twig' list: 'SonataAdminBundle:CRUD:list.html.twig' show: 'SonataAdminBundle:CRUD:show.html.twig' show_compare: 'SonataAdminBundle:CRUD:show_compare.html.twig' edit: 'SonataAdminBundle:CRUD:edit.html.twig'

...

Page 123: Cómo domar SonataAdminBundle

Sobrescribir templates

# app/config/config.yml

sonata_admin: templates: user_block: 'SonataAdminBundle:Core:user_block.html.twig' add_block: 'SonataAdminBundle:Core:add_block.html.twig' layout: 'SonataAdminBundle::standard_layout.html.twig' ajax: 'SonataAdminBundle::ajax_layout.html.twig' dashboard: 'SonataAdminBundle:Core:dashboard.html.twig' search: 'SonataAdminBundle:Core:search.html.twig' list: 'SonataAdminBundle:CRUD:list.html.twig' show: 'SonataAdminBundle:CRUD:show.html.twig' show_compare: 'SonataAdminBundle:CRUD:show_compare.html.twig' edit: 'AppBundle:Admin:edit.html.twig'

...

Page 124: Cómo domar SonataAdminBundle

Sobrescribir templates

# app/config/config.yml

sonata_admin: templates: user_block: 'SonataAdminBundle:Core:user_block.html.twig' add_block: 'SonataAdminBundle:Core:add_block.html.twig' layout: 'SonataAdminBundle::standard_layout.html.twig' ajax: 'SonataAdminBundle::ajax_layout.html.twig' dashboard: 'SonataAdminBundle:Core:dashboard.html.twig' search: 'SonataAdminBundle:Core:search.html.twig' list: 'SonataAdminBundle:CRUD:list.html.twig' show: 'SonataAdminBundle:CRUD:show.html.twig' show_compare: 'SonataAdminBundle:CRUD:show_compare.html.twig' edit: 'AppBundle:Admin:edit.html.twig'

...

Fundamental buscar la template original y ver qué queremos sobrescribir exactamente

Page 125: Cómo domar SonataAdminBundle

Sobrescribir templates

# vendor/sonata-project/admin-bundle/Resources/views/CRUD/edit.html.twig

{% extends 'SonataAdminBundle:CRUD:base_edit.html.twig' %}

Page 126: Cómo domar SonataAdminBundle

Sobrescribir templates

# vendor/sonata-project/admin-bundle/Resources/views/CRUD/edit.html.twig

{% extends 'SonataAdminBundle:CRUD:base_edit.html.twig' %}

# vendor/sonata-project/admin-bundle/Resources/views/CRUD/base_edit.html.twig

{% block formactions %}...{% block formactions %}

Page 127: Cómo domar SonataAdminBundle

Screenshots (III): Sobrescribir templates

Page 128: Cómo domar SonataAdminBundle

Screenshots (III): Sobrescribir templates

Page 129: Cómo domar SonataAdminBundle

¿Y si solo quiero sobrescribir la template de un Admin concreto?

Page 130: Cómo domar SonataAdminBundle

Sobrescribir templates

# app/config/services.yml

services: admin.regalo: class: AppBundle\Admin\RegaloAdmin arguments: [~, AppBundle\Entity\Regalo, ~] tags: - { name: sonata.admin, manager_type: orm, label: Regalos }

Page 131: Cómo domar SonataAdminBundle

Sobrescribir templates

# app/config/services.yml

services: admin.regalo: class: AppBundle\Admin\RegaloAdmin arguments: [~, AppBundle\Entity\Regalo, ~] tags: - { name: sonata.admin, manager_type: orm, label: Regalos } calls: - [ setTemplate, [edit, :Admin:edit_regalo.html.twig]]

Page 132: Cómo domar SonataAdminBundle

Screenshots (III): Sobrescribir templates

Page 133: Cómo domar SonataAdminBundle

¿Cómo sobrescribo la template de un campo concreto del listado?

Page 134: Cómo domar SonataAdminBundle

Sobrescribir la template de un field en el list

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureListFields(ListMapper $listMapper) { $listMapper

...

; }

Page 135: Cómo domar SonataAdminBundle

Sobrescribir la template de un field en el list (paso 1)

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureListFields(ListMapper $listMapper) { $listMapper

...

->add('miField', 'string', array('template' => ':Admin:field_envio_email.html.twig'))

; }

Page 136: Cómo domar SonataAdminBundle

Sobrescribir la template de un field en el list (paso 1)

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureListFields(ListMapper $listMapper) { $listMapper

...

->add('miField', 'string', array('template' => ':Admin:field_envio_email.html.twig'))

; }

Page 137: Cómo domar SonataAdminBundle

Sobrescribir la template de un field en el list (paso 2)

# app/Resources/views/Admin/field_envio_email.html.twig

{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}

{% block field %}<a class="btn btn-primary btn-sm" href="">

<i class="fa fa-envelope"></i> Enviar</a>{% endblock %}

Page 138: Cómo domar SonataAdminBundle

Screenshots (III): Sobrescribir la template de un field en el list

Page 139: Cómo domar SonataAdminBundle

Modificando las queries

Page 140: Cómo domar SonataAdminBundle

Screenshots (III): Modificar la query del list

Page 141: Cómo domar SonataAdminBundle

Modificar la query del list

# src/AppBundle/Admin/RegaloAdmin.php

public function createQuery($context = 'list') { $query = parent::createQuery($context); $rootAlias = $query->getRootAliases()[0]; $query ->andWhere( $query->expr()->eq($rootAlias.'.entregado', ':entregado')); $query->setParameter('entregado', false);

return $query; }

Page 142: Cómo domar SonataAdminBundle

Modificar la query del list

# src/AppBundle/Admin/RegaloAdmin.php

public function createQuery($context = 'list') { $query = parent::createQuery($context); $rootAlias = $query->getRootAliases()[0]; $query ->andWhere( $query->expr()->eq($rootAlias.'.entregado', ':entregado')); $query->setParameter('entregado', false);

return $query; }

Page 143: Cómo domar SonataAdminBundle

Screenshots (III): Modificar la query del list

Page 144: Cómo domar SonataAdminBundle

Screenshots (III): Modificar la query de un filtro

Page 145: Cómo domar SonataAdminBundle

Screenshots (III): Modificar la query de un filtro

Page 146: Cómo domar SonataAdminBundle

Screenshots (III): Modificar la query de un filtro

Page 147: Cómo domar SonataAdminBundle

Modificar la query de un filtro

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureDatagridFilters(DatagridMapper $datagridMapper) { $datagridMapper ->add('miFiltro', 'doctrine_orm_callback',array( 'callback' => function($queryBuilder, $alias, $field, $value) { if (!$value['value']) { return; }

$queryBuilder->andWhere($alias.'.estado != :estado'); $queryBuilder->setParameter('estado', 'entregado');

return true; }, 'field_type' => 'checkbox', 'label' => 'No entregados' )) ; }

Page 148: Cómo domar SonataAdminBundle

Modificar la query de un filtro

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureDatagridFilters(DatagridMapper $datagridMapper) { $datagridMapper ->add('miFiltro', 'doctrine_orm_callback',array( 'callback' => function($queryBuilder, $alias, $field, $value) { if (!$value['value']) { return; }

$queryBuilder->andWhere($alias.'.estado != :estado'); $queryBuilder->setParameter('estado', 'entregado');

return true; }, 'field_type' => 'checkbox', 'label' => 'No entregados' )) ; }

Page 149: Cómo domar SonataAdminBundle

Modificar la query de un filtro

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureDatagridFilters(DatagridMapper $datagridMapper) { $datagridMapper ->add('miFiltro', 'doctrine_orm_callback',array( 'callback' => function($queryBuilder, $alias, $field, $value) { if (!$value['value']) { return; }

$queryBuilder->andWhere($alias.'.estado != :estado'); $queryBuilder->setParameter('estado', 'entregado');

return true; }, 'field_type' => 'checkbox', 'label' => 'No entregados' )) ; }

Page 150: Cómo domar SonataAdminBundle

Modificar la query de un filtro

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureDatagridFilters(DatagridMapper $datagridMapper) { $datagridMapper ->add('miFiltro', 'doctrine_orm_callback',array( 'callback' => function($queryBuilder, $alias, $field, $value) { if (!$value['value']) { return; }

$queryBuilder->andWhere($alias.'.estado != :estado'); $queryBuilder->setParameter('estado', 'entregado');

return true; }, 'field_type' => 'checkbox', 'label' => 'No entregados' )) ; }

Page 151: Cómo domar SonataAdminBundle

Screenshots (III): Modificar la query de un filtro

Page 152: Cómo domar SonataAdminBundle

Screenshots (III): Modificar la query de un filtro

Page 153: Cómo domar SonataAdminBundle

Escribiendo en el controlador

Page 154: Cómo domar SonataAdminBundle

Screenshots (III): Crear un action custom

Page 155: Cómo domar SonataAdminBundle

Crear un action custom (paso 1)

# src/AppBundle/Controller/RegaloAdminController.php

use Sonata\AdminBundle\Controller\CRUDController as Controller;use Symfony\Component\HttpFoundation\RedirectResponse;

class RegaloAdminController extends Controller{ public function sendEmailAction() { $regalo = $this->admin->getSubject(); $email = $regalo->getDestinatario()->getEmail();

// Here code to send email

$this->addFlash('sonata_flash_success', 'Email enviado a '.$email);

return new RedirectResponse($this->admin->generateUrl('list')); }}

Page 156: Cómo domar SonataAdminBundle

Crear un action custom (paso 1)

# src/AppBundle/Controller/RegaloAdminController.php

use Sonata\AdminBundle\Controller\CRUDController as Controller;use Symfony\Component\HttpFoundation\RedirectResponse;

class RegaloAdminController extends Controller{ public function sendEmailAction() { $regalo = $this->admin->getSubject(); $email = $regalo->getDestinatario()->getEmail();

// Here code to send email

$this->addFlash('sonata_flash_success', 'Email enviado a '.$email);

return new RedirectResponse($this->admin->generateUrl('list')); }}

Page 157: Cómo domar SonataAdminBundle

Crear un action custom (paso 1)

# src/AppBundle/Controller/RegaloAdminController.php

use Sonata\AdminBundle\Controller\CRUDController as Controller;use Symfony\Component\HttpFoundation\RedirectResponse;

class RegaloAdminController extends Controller{ public function sendEmailAction() { $regalo = $this->admin->getSubject(); $email = $regalo->getDestinatario()->getEmail();

// Here code to send email

$this->addFlash('sonata_flash_success', 'Email enviado a '.$email);

return new RedirectResponse($this->admin->generateUrl('list')); }}

Page 158: Cómo domar SonataAdminBundle

Crear un action custom (paso 2)

# app/config/services.yml

services: admin.regalo: class: AppBundle\Admin\RegaloAdmin arguments: [~, AppBundle\Entity\Regalo, ~] tags: - { name: sonata.admin, manager_type: orm, label: Regalos } calls: - [ setTemplate, [edit, :Admin:edit_regalo.html.twig]]

Page 159: Cómo domar SonataAdminBundle

Crear un action custom (paso 2)

# app/config/services.yml

services: admin.regalo: class: AppBundle\Admin\RegaloAdmin arguments: [~, AppBundle\Entity\Regalo, AppBundle\RegaloAdmin] tags: - { name: sonata.admin, manager_type: orm, label: Regalos } calls: - [ setTemplate, [edit, :Admin:edit_regalo.html.twig]]

Page 160: Cómo domar SonataAdminBundle

Crear un action custom (paso 3)

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureRoutes(RouteCollection $collection) { $collection->add('sendEmail', $this->getRouterIdParameter().'/send-email'); }

Page 161: Cómo domar SonataAdminBundle

Crear un action custom (paso 3)

# src/AppBundle/Admin/RegaloAdmin.php

protected function configureRoutes(RouteCollection $collection) { $collection->add('sendEmail', $this->getRouterIdParameter().'/send-email'); }

Page 162: Cómo domar SonataAdminBundle

Crear un action custom

# app/Resources/views/Admin/field_envio_email.html.twig

{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}

{% block field %}<a class="btn btn-primary btn-sm" href="">

<i class="fa fa-envelope"></i> Enviar</a>{% endblock %}

Page 163: Cómo domar SonataAdminBundle

Crear un action custom

# app/Resources/views/Admin/field_envio_email.html.twig

{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}

{% block field %}<a class="btn btn-primary btn-sm" href="{{

admin.generateObjectUrl('sendEmail', object) }}"> <i class="fa fa-envelope"></i> Enviar

</a>{% endblock %}

Page 164: Cómo domar SonataAdminBundle

Screenshots (III): Crear un action custom

Page 165: Cómo domar SonataAdminBundle

Screenshots (III): Crear una batch action custom

Page 166: Cómo domar SonataAdminBundle

Crear un batch action custom (paso 1)

# src/AppBundle/Controller/RegaloAdminController.php

public function batchActionSendEmail($selectedModelQuery) {

// Here code to send emails

return new RedirectResponse($this->admin->generateUrl('list')); }

Page 167: Cómo domar SonataAdminBundle

Crear un batch action custom (paso 1)

# src/AppBundle/Controller/RegaloAdminController.php

public function batchActionSendEmail($selectedModelQuery) {

// Here code to send emails

return new RedirectResponse($this->admin->generateUrl('list')); }

Page 168: Cómo domar SonataAdminBundle

Crear un batch action custom (paso 2)

# src/AppBundle/Admin/RegaloAdmin.php

public function getBatchActions() { $actions = parent::getBatchActions();

if ($this->hasRoute('edit') && $this->isGranted('EDIT')) { $actions['send_email'] = [ 'label' => 'Enviar email', 'ask_confirmation' => false, ]; }

return $actions; }

Page 169: Cómo domar SonataAdminBundle

Crear un batch action custom (paso 2)

# src/AppBundle/Admin/RegaloAdmin.php

public function getBatchActions() { $actions = parent::getBatchActions();

if ($this->hasRoute('edit') && $this->isGranted('EDIT')) { $actions['send_email'] = [ 'label' => 'Enviar email', 'ask_confirmation' => false, ]; }

return $actions; }

Page 170: Cómo domar SonataAdminBundle

Screenshots (III): Crear una batch action custom

Page 171: Cómo domar SonataAdminBundle

IV. Consejos prácticos

O conjunto de ideas varias que pueden venir bien en cualquier proyecto

Page 172: Cómo domar SonataAdminBundle

¿Cómo toco el aspecto general del panel?

Page 173: Cómo domar SonataAdminBundle

Aspecto general

Page 174: Cómo domar SonataAdminBundle

Aspecto general

Page 175: Cómo domar SonataAdminBundle

Aspecto general

# app/config/config.yml

sonata_admin: title: deSymfony

Page 176: Cómo domar SonataAdminBundle

Aspecto general

# app/config/config.yml

sonata_admin: title: deSymfony title_logo: 'img/logo.png'

Page 177: Cómo domar SonataAdminBundle

Aspecto general

# app/config/config.yml

sonata_admin: title: deSymfony title_logo: 'img/logo.png' assets: stylesheets: - bundles/sonatacore/vendor/bootstrap/dist/css/bootstrap.min.css - bundles/sonatacore/vendor/ionicons/css/ionicons.min.css - bundles/sonataadmin/vendor/admin-lte/dist/css/AdminLTE.min.css - bundles/sonataadmin/vendor/admin-lte/dist/css/skins/skin-black.min.css - bundles/sonataadmin/vendor/iCheck/skins/square/blue.css - bundles/sonataadmin/vendor/jqueryui/themes/base/jquery-ui.css - bundles/sonatacore/vendor/select2/select2.css - bundles/sonataadmin/css/styles.css - bundles/sonataadmin/css/layout.css - bundles/sonataadmin/css/tree.css - bundles/sonataadmin/css/colors.css

Page 178: Cómo domar SonataAdminBundle

Aspecto general

# app/config/config.yml

sonata_admin: title: deSymfony title_logo: 'img/logo.png' assets: stylesheets: - bundles/sonatacore/vendor/bootstrap/dist/css/bootstrap.min.css - bundles/sonatacore/vendor/ionicons/css/ionicons.min.css - bundles/sonataadmin/vendor/admin-lte/dist/css/AdminLTE.min.css - bundles/sonataadmin/vendor/admin-lte/dist/css/skins/skin-black.min.css - bundles/sonataadmin/vendor/iCheck/skins/square/blue.css - bundles/sonataadmin/vendor/jqueryui/themes/base/jquery-ui.css - bundles/sonatacore/vendor/select2/select2.css - bundles/sonataadmin/css/styles.css - bundles/sonataadmin/css/layout.css - bundles/sonataadmin/css/tree.css - bundles/sonataadmin/css/colors.css

https://sonata-project.org/bundles/admin/master/doc/reference/configuration.html

Page 179: Cómo domar SonataAdminBundle

Aspecto general

# app/config/config.yml

sonata_admin: title: deSymfony title_logo: 'img/logo.png' assets: stylesheets: - bundles/sonatacore/vendor/bootstrap/dist/css/bootstrap.min.css - bundles/sonatacore/vendor/ionicons/css/ionicons.min.css - bundles/sonataadmin/vendor/admin-lte/dist/css/AdminLTE.min.css - bundles/sonataadmin/vendor/admin-lte/dist/css/skins/skin-black.min.css - bundles/sonataadmin/vendor/iCheck/skins/square/blue.css - bundles/sonataadmin/vendor/jqueryui/themes/base/jquery-ui.css - bundles/sonatacore/vendor/select2/select2.css - bundles/sonataadmin/css/styles.css - bundles/sonataadmin/css/layout.css - bundles/sonataadmin/css/tree.css - bundles/sonataadmin/css/colors.css - css/styles.css

Page 180: Cómo domar SonataAdminBundle

Aspecto general

Page 181: Cómo domar SonataAdminBundle

Aspecto general

# app/config/config.yml

sonata_admin: title: deSymfony title_logo: 'img/logo.png' assets: stylesheets: - bundles/sonatacore/vendor/bootstrap/dist/css/bootstrap.min.css - bundles/sonatacore/vendor/ionicons/css/ionicons.min.css - bundles/sonataadmin/vendor/admin-lte/dist/css/AdminLTE.min.css - bundles/sonataadmin/vendor/admin-lte/dist/css/skins/skin-black.min.css - bundles/sonataadmin/vendor/iCheck/skins/square/blue.css - bundles/sonataadmin/vendor/jqueryui/themes/base/jquery-ui.css - bundles/sonatacore/vendor/select2/select2.css - bundles/sonataadmin/css/styles.css - bundles/sonataadmin/css/layout.css - bundles/sonataadmin/css/tree.css - bundles/sonataadmin/css/colors.css - css/styles.css

Page 182: Cómo domar SonataAdminBundle

Aspecto general

# app/config/config.yml

sonata_admin: title: deSymfony title_logo: 'img/logo.png' assets: stylesheets: - bundles/sonatacore/vendor/bootstrap/dist/css/bootstrap.min.css - bundles/sonatacore/vendor/ionicons/css/ionicons.min.css - bundles/sonataadmin/vendor/admin-lte/dist/css/AdminLTE.min.css - bundles/sonataadmin/vendor/admin-lte/dist/css/skins/skin-black.min.css - bundles/sonataadmin/vendor/iCheck/skins/square/blue.css - bundles/sonataadmin/vendor/jqueryui/themes/base/jquery-ui.css - bundles/sonatacore/vendor/select2/select2.css - bundles/sonataadmin/css/styles.css - bundles/sonataadmin/css/layout.css - bundles/sonataadmin/css/tree.css - bundles/sonataadmin/css/colors.css - css/styles.css

Page 183: Cómo domar SonataAdminBundle

Aspecto general

# app/config/config.yml

sonata_admin: title: deSymfony title_logo: 'img/logo.png' assets: stylesheets: - bundles/sonatacore/vendor/bootstrap/dist/css/bootstrap.min.css - bundles/sonatacore/vendor/ionicons/css/ionicons.min.css - bundles/sonataadmin/vendor/admin-lte/dist/css/AdminLTE.min.css - bundles/sonataadmin/vendor/admin-lte/dist/css/skins/skin-black.min.css

https://almsaeedstudio.com/

Sonata utiliza AdminLTE, para lo visual generalmente hay que indagar allí

Page 184: Cómo domar SonataAdminBundle

Aspecto general - Layout

Page 185: Cómo domar SonataAdminBundle

Aspecto general - Layout

Page 186: Cómo domar SonataAdminBundle

Aspecto general - Layout

Page 187: Cómo domar SonataAdminBundle

Aspecto general - Layout

# app/config/config.yml

sonata_admin: templates: user_block: 'SonataAdminBundle:Core:user_block.html.twig' add_block: 'SonataAdminBundle:Core:add_block.html.twig' layout: 'SonataAdminBundle::standard_layout.html.twig' ajax: 'SonataAdminBundle::ajax_layout.html.twig' dashboard: 'SonataAdminBundle:Core:dashboard.html.twig' search: 'SonataAdminBundle:Core:search.html.twig' list: 'SonataAdminBundle:CRUD:list.html.twig' show: 'SonataAdminBundle:CRUD:show.html.twig' show_compare: 'SonataAdminBundle:CRUD:show_compare.html.twig' edit: 'SonataAdminBundle:CRUD:edit.html.twig'

...

Page 188: Cómo domar SonataAdminBundle

Aspecto general - Layout

# app/config/config.yml

sonata_admin: templates: user_block: 'SonataAdminBundle:Core:user_block.html.twig' add_block: 'SonataAdminBundle:Core:add_block.html.twig' layout: 'SonataAdminBundle::standard_layout.html.twig' ajax: 'SonataAdminBundle::ajax_layout.html.twig' dashboard: 'SonataAdminBundle:Core:dashboard.html.twig' search: 'SonataAdminBundle:Core:search.html.twig' list: 'SonataAdminBundle:CRUD:list.html.twig' show: 'SonataAdminBundle:CRUD:show.html.twig' show_compare: 'SonataAdminBundle:CRUD:show_compare.html.twig' edit: 'SonataAdminBundle:CRUD:edit.html.twig'

...

Page 189: Cómo domar SonataAdminBundle

Aspecto general - Layout

# app/config/config.yml

sonata_admin: templates: user_block: 'SonataAdminBundle:Core:user_block.html.twig' add_block: 'SonataAdminBundle:Core:add_block.html.twig' layout: ':Admin:layout.html.twig' ajax: 'SonataAdminBundle::ajax_layout.html.twig' dashboard: 'SonataAdminBundle:Core:dashboard.html.twig' search: 'SonataAdminBundle:Core:search.html.twig' list: 'SonataAdminBundle:CRUD:list.html.twig' show: 'SonataAdminBundle:CRUD:show.html.twig' show_compare: 'SonataAdminBundle:CRUD:show_compare.html.twig' edit: 'SonataAdminBundle:CRUD:edit.html.twig'

...

Page 190: Cómo domar SonataAdminBundle

Aspecto general - Layout

Page 191: Cómo domar SonataAdminBundle

Aspecto general - Dashboard

Page 192: Cómo domar SonataAdminBundle

Aspecto general - Dashboard

# app/config/config.yml

sonata_admin: templates: user_block: 'SonataAdminBundle:Core:user_block.html.twig' add_block: 'SonataAdminBundle:Core:add_block.html.twig' layout: 'SonataAdminBundle::standard_layout.html.twig' ajax: 'SonataAdminBundle::ajax_layout.html.twig' dashboard: 'SonataAdminBundle:Core:dashboard.html.twig' search: 'SonataAdminBundle:Core:search.html.twig' list: 'SonataAdminBundle:CRUD:list.html.twig' show: 'SonataAdminBundle:CRUD:show.html.twig' show_compare: 'SonataAdminBundle:CRUD:show_compare.html.twig' edit: 'SonataAdminBundle:CRUD:edit.html.twig'

...

Page 193: Cómo domar SonataAdminBundle

Aspecto general - Dashboard

# app/config/config.yml

sonata_admin: templates: user_block: 'SonataAdminBundle:Core:user_block.html.twig' add_block: 'SonataAdminBundle:Core:add_block.html.twig' layout: 'SonataAdminBundle::standard_layout.html.twig' ajax: 'SonataAdminBundle::ajax_layout.html.twig' dashboard: 'SonataAdminBundle:Core:dashboard.html.twig' search: 'SonataAdminBundle:Core:search.html.twig' list: 'SonataAdminBundle:CRUD:list.html.twig' show: 'SonataAdminBundle:CRUD:show.html.twig' show_compare: 'SonataAdminBundle:CRUD:show_compare.html.twig' edit: 'SonataAdminBundle:CRUD:edit.html.twig'

...

Page 194: Cómo domar SonataAdminBundle

Aspecto general - Dashboard

# app/config/config.yml

sonata_admin: templates: user_block: 'SonataAdminBundle:Core:user_block.html.twig' add_block: 'SonataAdminBundle:Core:add_block.html.twig' layout: 'SonataAdminBundle::standard_layout.html.twig' ajax: 'SonataAdminBundle::ajax_layout.html.twig' dashboard: ':Admin:dashboard.html.twig' search: 'SonataAdminBundle:Core:search.html.twig' list: 'SonataAdminBundle:CRUD:list.html.twig' show: 'SonataAdminBundle:CRUD:show.html.twig' show_compare: 'SonataAdminBundle:CRUD:show_compare.html.twig' edit: 'SonataAdminBundle:CRUD:edit.html.twig'

...

Page 195: Cómo domar SonataAdminBundle

Aspecto general - Dashboard

Page 196: Cómo domar SonataAdminBundle

Aspecto general - Dashboard

Page 197: Cómo domar SonataAdminBundle

Aspecto general - Dashboard

Page 198: Cómo domar SonataAdminBundle

¿Puedo hacer dos admins de la misma entidad?

Page 199: Cómo domar SonataAdminBundle

Crear dos admins de la misma entidad

# src/AppBundle/Admin/RegaloPasadoAdmin.php

class RegaloPasadoAdmin extends Admin

{

}

Sin problema. Creamos una nueva clase Admin…

Page 200: Cómo domar SonataAdminBundle

Crear dos admins de la misma entidad

# src/AppBundle/Admin/RegaloPasadoAdmin.php

class RegaloPasadoAdmin extends Admin

{

protected $baseRouteName = 'regalo_pasado'; protected $baseRoutePattern = 'regalo-pasado'

...}

(sin olvidar estas propiedades para que Sonata no se líe con el routing)

Page 201: Cómo domar SonataAdminBundle

Crear dos admins de la misma entidad

# app/config/services.yml

services: admin.regalo: class: AppBundle\Admin\RegaloAdmin arguments: [~, AppBundle\Entity\Regalo, AppBundle:RegaloAdmin] tags: - { name: sonata.admin, manager_type: orm, label: Regalos } calls: - [ setTemplate, [edit, :Admin:edit_regalo.html.twig]]

… y registramos el nuevo servicio

Page 202: Cómo domar SonataAdminBundle

Crear dos admins de la misma entidad

# app/config/services.yml

services: admin.regalo: class: AppBundle\Admin\RegaloAdmin arguments: [~, AppBundle\Entity\Regalo, AppBundle:RegaloAdmin] tags: - { name: sonata.admin, manager_type: orm, label: Activos } calls: - [ setTemplate, [edit, :Admin:edit_regalo.html.twig]] admin.regalo_pasado: class: AppBundle\Admin\RegaloPasadoAdmin arguments: [~, AppBundle\Entity\Regalo, ~] tags: - { name: sonata.admin, manager_type: orm, label: Pasados }

… y registramos el nuevo servicio

Page 203: Cómo domar SonataAdminBundle

Crear dos admins de la misma entidad

Page 204: Cómo domar SonataAdminBundle

Crear dos admins de la misma entidad

Page 205: Cómo domar SonataAdminBundle

Crear dos admins de la misma entidad

Page 206: Cómo domar SonataAdminBundle

Admin como child en el menú de otro Admin

Page 207: Cómo domar SonataAdminBundle

Admin como child en el menú de otro Admin

Page 208: Cómo domar SonataAdminBundle

Admin como child en el menú de otro Admin

Page 209: Cómo domar SonataAdminBundle

Admin como child en el menú de otro Admin

# app/config/services.yml

admin.comprador: class: AppBundle\Admin\CompradorAdmin arguments: [~, AppBundle\Entity\Comprador, ~] tags: - { name: sonata.admin, manager_type: orm, label: Compradores } calls: - [ addChild, [ '@admin.pago' ] ] admin.pago: class: AppBundle\Admin\PagoAdmin arguments: [~, AppBundle\Entity\Pago, ~] tags: - { name: sonata.admin, manager_type: orm, label: Pagos }

Page 210: Cómo domar SonataAdminBundle

Admin como child en el menú de otro Admin

# app/config/services.yml

admin.comprador: class: AppBundle\Admin\CompradorAdmin arguments: [~, AppBundle\Entity\Comprador, ~] tags: - { name: sonata.admin, manager_type: orm, label: Compradores } calls: - [ addChild, [ '@admin.pago' ] ] admin.pago: class: AppBundle\Admin\PagoAdmin arguments: [~, AppBundle\Entity\Pago, ~] tags: - { name: sonata.admin, manager_type: orm, label: Pagos }

Page 211: Cómo domar SonataAdminBundle

Admin como child en el menú de otro Admin

# app/config/services.yml

admin.comprador: class: AppBundle\Admin\CompradorAdmin arguments: [~, AppBundle\Entity\Comprador, ~] tags: - { name: sonata.admin, manager_type: orm, label: Compradores } calls: - [ addChild, [ '@admin.pago' ] ] admin.pago: class: AppBundle\Admin\PagoAdmin arguments: [~, AppBundle\Entity\Pago, ~] tags: - { name: sonata.admin, manager_type: orm, label: Pagos }

Page 212: Cómo domar SonataAdminBundle

Admin como child en el menú de otro Admin

# app/config/config.yml

admin.comprador: class: AppBundle\Admin\CompradorAdmin arguments: [~, AppBundle\Entity\Comprador, ~] tags: - { name: sonata.admin, manager_type: orm, label: Compradores } calls: - [ addChild, [ '@admin.pago' ] ] admin.pago: class: AppBundle\Admin\PagoAdmin arguments: [~, AppBundle\Entity\Pago, ~] tags: - { name: sonata.admin, manager_type: orm, label: Pagos }

Page 213: Cómo domar SonataAdminBundle

Admin como child en el menú de otro Admin

# src/AppBundle/Admin/CompradorAdmin.php

protected function configureSideMenu(ItemInterface $menu, $action, AdminInterface $childAdmin = null) {

... $menu->addChild( 'Pagos', $admin->generateMenuUrl('admin.comprador|admin.pago.list', array('id' => $id)) ); }

Page 214: Cómo domar SonataAdminBundle

Admin como child en el menú de otro Admin

# src/AppBundle/Admin/CompradorAdmin.php

protected function configureSideMenu(ItemInterface $menu, $action, AdminInterface $childAdmin = null) {

... $menu->addChild( 'Pagos', $admin->generateMenuUrl('admin.comprador|admin.pago.list', array('id' => $id)) ); }

Page 215: Cómo domar SonataAdminBundle

Admin como child en el menú de otro Admin

Page 216: Cómo domar SonataAdminBundle

¿Qué pasa si el listado no es lo principal?

Page 217: Cómo domar SonataAdminBundle

Enlazar un action custom desde la sidebar

Creamos nuestro action custom, la template y la ruta...

Page 218: Cómo domar SonataAdminBundle

Enlazar un action custom desde la sidebar

# app/config/config.yml

dashboard: groups:

... demo.admin.settings: label: Configuración label_catalogue: AppBundle icon: '<i class="fa fa-gear"></i>' items: - admin.configuracion

Creamos nuestro action custom, la template y la ruta...

… la enlazamos desde el sidebar

Page 219: Cómo domar SonataAdminBundle

Enlazar un action custom desde la sidebar

# app/config/config.yml

dashboard: groups:

... demo.admin.settings: label: Configuración label_catalogue: AppBundle icon: '<i class="fa fa-gear"></i>' items: - admin.configuracion - route: config_myEdit label: 'Mi configuración'

Creamos nuestro action custom, la template y la ruta...

… la enlazamos desde el sidebar

Page 220: Cómo domar SonataAdminBundle

Enlazar un action custom desde la sidebar

Page 221: Cómo domar SonataAdminBundle

¿Y si quiero meter algo que no sea un Admin?

Page 222: Cómo domar SonataAdminBundle

Toda tu aplicación puede estar dentro de Sonata

Tu aplicación puede tener partes que no sean un Admin

Y sin embargo estén integradas con lo demás

Puedes meter cualquier cosa ahí dentro

Page 223: Cómo domar SonataAdminBundle

Toda tu aplicación puede estar dentro de Sonata

Page 224: Cómo domar SonataAdminBundle

Toda tu aplicación puede estar dentro de Sonata

Page 225: Cómo domar SonataAdminBundle

Toda tu aplicación puede estar dentro de Sonata

Creas tu action en el controlador (PacienteAdminController.php)

Page 226: Cómo domar SonataAdminBundle

Toda tu aplicación puede estar dentro de Sonata

Creas tu action en el controlador (PacienteAdminController.php)

Configuras tu ruta en configureRoutes (PacienteAdmin.php)

$collection->add('editor', $this->getRouterIdParameter().'/editor');

Page 227: Cómo domar SonataAdminBundle

Toda tu aplicación puede estar dentro de Sonata

Creas tu action en el controlador (PacienteAdminController.php)

Configuras tu ruta en configureRoutes (PacienteAdmin.php)

$collection->add('editor', $this->getRouterIdParameter().'/editor');

Haces setTemplate en la declaración del servicio (services.yml)

<call method="setTemplates">

<argument type="collection">

<argument key="editor">:editor:editor.html.twig</argument>

</argument>

</call>

Page 228: Cómo domar SonataAdminBundle

V. Más allá

O qué otras cosas hay ahí fuera y dónde puedo encontrarlas

Page 229: Cómo domar SonataAdminBundle

Documentación de SonataAdminBundle

Page 230: Cómo domar SonataAdminBundle

FOSUserBundle & SonataUserAdminBundle

SonataUserAdminBundle es una capa sobre FOSUserBundle que aporta algunas cosas

(pero no es imprescindible para usar FOSUserBundle)

https://sonata-project.org/bundles/user/3-x/doc/reference/introduction.html

Page 231: Cómo domar SonataAdminBundle

Seguridad, roles

https://sonata-project.org/bundles/admin/3-x/doc/reference/security.html

La seguridad se puede configurar de muchas formas distintas y con tanto detalle como quieras

Page 232: Cómo domar SonataAdminBundle

Eventos

https://sonata-project.org/bundles/admin/3-x/doc/reference/events.html

Hay una serie de eventos definidos por Sonata que pueden resultar muy útiles

● sonata.admin.event.persistence.pre_update

● sonata.admin.event.persistence.post_update

● sonata.admin.event.persistence.pre_persist

● sonata.admin.event.persistence.post_persist

● sonata.admin.event.persistence.pre_remove

● sonata.admin.event.persistence.post_remove

Page 233: Cómo domar SonataAdminBundle

Sonata Project Demo

Page 234: Cómo domar SonataAdminBundle

Sonata Project Demo

Page 235: Cómo domar SonataAdminBundle

Sonata Project Demo

Page 236: Cómo domar SonataAdminBundle

Y a la hora de la verdad.. pues el código

Page 237: Cómo domar SonataAdminBundle

Admin class

Conviene mucho mirarse la Admin class

vendor/sonata-project/admin-bundle/Admin/AbstractAdmin.php

Page 238: Cómo domar SonataAdminBundle

VI. Conclusiones

O con qué me quedo de todo esto

Page 239: Cómo domar SonataAdminBundle

Conclusiones

● Los principales problemas se han ido solucionando. Y sigue mejorando.

Page 240: Cómo domar SonataAdminBundle

Conclusiones

● Los principales problemas se han ido solucionando. Y sigue mejorando.

● Te da MUCHO hecho. Hay que sacar el máximo provecho a esa parte.

Page 241: Cómo domar SonataAdminBundle

Conclusiones

● Los principales problemas se han ido solucionando. Y sigue mejorando.

● Te da MUCHO hecho. Hay que sacar el máximo provecho a esa parte.

● Puedes sobrescribir lo que quieras y meter tu propio código donde quieras.

Page 242: Cómo domar SonataAdminBundle

Conclusiones

Te permite solucionar un problema aburrido de una forma eficiente

Page 243: Cómo domar SonataAdminBundle

Conclusiones

Te permite solucionar un problema aburrido de una forma eficiente

Para que puedas dedicarte a otra cosa más emocionante

Page 244: Cómo domar SonataAdminBundle

Conclusiones

Y desde el punto de vista del negocio suele ser muy buena decisión

Page 245: Cómo domar SonataAdminBundle

Victoria Quirante Ruiz Madrid, 16-17 Sep. 2016#deSymfony

@[email protected]

https://github.com/VictoriaQ/sonatademo

Formación, consultoría y desarrollo de proyectos

Page 246: Cómo domar SonataAdminBundle

Victoria Quirante Ruiz Madrid, 16-17 Sep. 2016#deSymfony

@[email protected]

https://github.com/VictoriaQ/sonatademo

Formación, consultoría y desarrollo de proyectos

Gracias!