child_admin.rst 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. Create child admins
  2. -------------------
  3. Let us say you have a ``PlaylistAdmin`` and a ``VideoAdmin``. You can optionally declare the ``VideoAdmin``
  4. to be a child of the ``PlaylistAdmin``. This will create new routes like, for example, ``/playlist/{id}/video/list``,
  5. where the videos will automatically be filtered by post.
  6. To do this, you first need to call the ``addChild`` method in your ``PlaylistAdmin`` service configuration:
  7. .. configuration-block::
  8. .. code-block:: xml
  9. <!-- app/config/config.xml -->
  10. <service id="sonata.admin.playlist" class="AppBundle\Admin\PlaylistAdmin">
  11. <!-- ... -->
  12. <call method="addChild">
  13. <argument type="service" id="sonata.admin.video" />
  14. </call>
  15. </service>
  16. Then, you have to set the VideoAdmin ``parentAssociationMapping`` attribute to ``playlist`` :
  17. .. code-block:: php
  18. <?php
  19. namespace AppBundle\Admin;
  20. // ...
  21. class VideoAdmin extends AbstractAdmin
  22. {
  23. protected $parentAssociationMapping = 'playlist';
  24. // OR
  25. public function getParentAssociationMapping()
  26. {
  27. return 'playlist';
  28. }
  29. }
  30. To display the ``VideoAdmin`` extend the menu in your ``PlaylistAdmin`` class:
  31. .. code-block:: php
  32. <?php
  33. namespace AppBundle\Admin;
  34. use Knp\Menu\ItemInterface as MenuItemInterface;
  35. use Sonata\AdminBundle\Admin\AbstractAdmin;
  36. use Sonata\AdminBundle\Admin\AdminInterface;
  37. class PlaylistAdmin extends AbstractAdmin
  38. {
  39. // ...
  40. protected function configureSideMenu(MenuItemInterface $menu, $action, AdminInterface $childAdmin = null)
  41. {
  42. if (!$childAdmin && !in_array($action, array('edit', 'show'))) {
  43. return;
  44. }
  45. $admin = $this->isChild() ? $this->getParent() : $this;
  46. $id = $admin->getRequest()->get('id');
  47. $menu->addChild('View Playlist', array('uri' => $admin->generateUrl('show', array('id' => $id))));
  48. if ($this->isGranted('EDIT')) {
  49. $menu->addChild('Edit Playlist', array('uri' => $admin->generateUrl('edit', array('id' => $id))));
  50. }
  51. if ($this->isGranted('LIST')) {
  52. $menu->addChild('Manage Videos', array(
  53. 'uri' => $admin->generateUrl('sonata.admin.video.list', array('id' => $id))
  54. ));
  55. }
  56. }
  57. }
  58. It also possible to set a dot-separated value, like ``post.author``, if your parent and child admins are not directly related.
  59. Be wary that being a child admin is optional, which means that regular routes
  60. will be created regardless of whether you actually need them or not. To get rid
  61. of them, you may override the ``configureRoutes`` method::
  62. <?php
  63. namespace AppBundle\Admin;
  64. use Sonata\AdminBundle\Admin\AbstractAdmin;
  65. use Sonata\AdminBundle\Route\RouteCollection;
  66. class VideoAdmin extends AbstractAdmin
  67. {
  68. protected $parentAssociationMapping = 'playlist';
  69. protected function configureRoutes(RouteCollection $collection)
  70. {
  71. if ($this->isChild()) {
  72. // This is the route configuration as a child
  73. $collection->clearExcept(['show', 'edit']);
  74. return;
  75. }
  76. // This is the route configuration as a parent
  77. $collection->clear();
  78. }
  79. }
  80. You can nest admins as deep as you wish.
  81. Let's say you want to add comments to videos.
  82. You can then add your ``CommentAdmin`` admin service as a child of
  83. the ``VideoAdmin`` admin service.
  84. Finally, the admin interface will look like this:
  85. .. figure:: ../images/child_admin.png
  86. :align: center
  87. :alt: Child admin interface
  88. :width: 700px