Browse Source

add wip recipe for custom action

Armin Weihbold 11 years ago
parent
commit
5ee2c01a1b
1 changed files with 226 additions and 0 deletions
  1. 226 0
      Resources/doc/reference/recipe_custom_action.rst

+ 226 - 0
Resources/doc/reference/recipe_custom_action.rst

@@ -0,0 +1,226 @@
+Creating a Custom Admin Action
+==============================
+
+This is a full working example of creating a custom list action for SonataAdmin.
+The Example is based on an existing ``CarAdmin`` in an ``AcmeDemoBundle``. It is
+assumed you already have and admin service up and running.
+
+The recipe
+----------
+
+SonataAdmin provides a very straight-forward way of adding your own custom actions.
+
+To do this we need to:
+
+- extend the  ``SonataAdmin:CRUD`` Controller and tell our admin class to use it
+- create the custom action in our Controller
+- create a template to show the action in list view
+- add the route and the new action in the Admin class
+
+Extending the Admin Controller
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+First we need to create or own Controller extending the one from SonataAdmin
+
+
+.. code-block:: php
+
+    <?php  // src/Acme/DemoBundle/Controller/CRUDController.php
+
+    namespace Acme\DemoBundle\Controller;
+
+    use Sonata\AdminBundle\Controller\CRUDController as Controller;
+
+    class CRUDController extends Controller
+    {
+
+        // ...
+    }
+
+Admin classes by default use ``SonataAdmin:CRUD`` controller , this is the third parameter
+of an admin service defintion, we need to change it to our own.
+
+Either by using XML:
+
+.. code-block:: xml
+
+        <!-- src/Acme/DemoBundle/Resources/config/admin.xml -->
+        ...
+
+        <service id="acme.demo.admin.car" class="Acme\DemoBundle\Admin\CarAdmin">
+
+            <tag name="sonata.admin" manager_type="orm" group="Demo" label="Car" />
+
+            <argument />
+            <argument>Acme\DemoBundle\Entity\Car</argument>
+            <argument>AcmeDemoBundle:CRUD</argument
+
+            ...
+
+        </service>
+
+        ...
+
+Or by overwriting the configuration in your ``config.yml``
+
+
+.. code-block:: yaml
+
+    # app/config/config.yml
+
+    services:
+        acme.demo.admin.car:
+            class: Acme\DemoBundle\Admin\CarAdmin
+            tags:
+                - { name: sonata.admin, manager_type: orm, group: Demo, label: Car }
+            arguments:
+                - null
+                - Acme\DemoBundle\Entity\Car
+                - AcmeDemoBundle:CRUD
+
+
+For more information about service configuration please refer to
+
+TODO: link
+
+
+Create the custom action in our Controller
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Now it's time to actually create your custom action here, for this example i chose
+to implement a ``clone`` action.
+
+.. code-block:: php
+
+    <?php // src/Acme/DemoBundle/Controller/CRUDController.php
+
+    namespace Acme\DemoBundle\Controller;
+
+    use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+    use Sonata\AdminBundle\Controller\CRUDController as Controller;
+    use Symfony\Component\HttpFoundation\RedirectResponse;
+
+    class CRUDController extends Controller
+    {
+
+        public function cloneAction()
+        {
+            $id = $this->get('request')->get($this->admin->getIdParameter());
+
+            $object = $this->admin->getObject($id);
+
+            if (!$object) {
+                throw new NotFoundHttpException(sprintf('unable to find the object with id : %s', $id));
+            }
+
+            $clonedObject = clone $object;
+            $clonedObject->setName($object->getName()." (Clone)");
+
+            $this->admin->create($clonedObject);
+
+            $this->addFlash('sonata_flash_success', 'Cloned successfully');
+
+            return new RedirectResponse($this->admin->generateUrl('list'));
+        }
+
+    }
+
+Here we first get the id of the object, see if it exists then clone it and insert the clone
+as new object. Finally we set a flash message indicating success and redirect to the list view.
+
+TODO: talk about other options or just refer to https://github.com/sonata-project/SonataAdminBundle/blob/master/Controller/CRUDController.php for reference?
+
+Create a template for the new action
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+
+We need to tell SonataAdmin how to render our new action we do that by creating a ``list__action_clone.html.twig`` in the
+namespace of our custom Admin Controller.
+
+
+.. code-block:: twig
+
+    {# src/Acme/DemoBundle/Resources/views/CRUD/list__action_clone.html.twig #}
+
+    <a href="{{ admin.generateObjectUrl('clone', object) }}">clone</a>
+
+Right now ``clone`` is not a known route, we define it in the next step.
+
+
+Bringing it all together
+^^^^^^^^^^^^^^^^^^^^^^^
+
+
+What's left now is actually adding our custom action to the admin class
+
+We have to add the new route in ``configureRoutes``
+
+.. code-block:: php
+
+    protected function configureRoutes(RouteCollection $collection)
+    {
+        $collection->add('clone', $this->getRouterIdParameter().'/clone');
+    }
+
+Which gives us a route like ``../admin/sonata/demo/car/1/clone``.
+You could also just do ``$collection->add('clone');`` to get a route like ``../admin/sonata/demo/car/clone?id=1``
+
+Next we have to add the action in ``configureListFields`` specifying the template we created.
+
+
+.. code-block:: php
+
+    protected function configureListFields(ListMapper $listMapper)
+    {
+        $listMapper
+
+             // other fields...
+
+            ->add('_action', 'actions', array( 'actions' => array(
+                'Clone' => array('template' =>
+                'AcmeDemoBundle:CRUD:list__action_clone.html.twig'))))
+        ;
+    }
+
+
+The full example ``CarAdmin.php`` looks like this:
+
+.. code-block:: php
+
+    <?php  // src/Acme/DemoBundle/Admin/CarAdmin.php
+
+    namespace Acme\DemoBundle\Admin;
+
+    // ...
+
+    use Sonata\AdminBundle\Route\RouteCollection;
+
+    class CarAdmin extends Admin
+    {
+         // ...
+
+        protected function configureListFields(ListMapper $listMapper)
+        {
+            $listMapper
+                ->addIdentifier('name')
+                ->add('engine')
+                ->add('rescueEngine')
+                ->add('createdAt')
+                ->add('_action', 'actions', array( 'actions' => array(
+                    'Clone' => array('template' =>
+                    'AcmeDemoBundle:CRUD:list__action_clone.html.twig'))))
+            ;
+        }
+
+        protected function configureRoutes(RouteCollection $collection)
+        {
+            $collection->add('clone', $this->getRouterIdParameter().'/clone');
+        }
+    }
+
+Final result looks like this:
+
+TODO: screenshot
+
+An example of this for ``CarAdmin`` in the AcmeDemoBundle of sonata-sandbox can be found here:
+https://github.com/koyaan/sandbox/commit/5bdbc3528ec095f697a9deec32a4bc8ca8d13321