diff --git a/docs/getting_started/creating_an_admin.rst b/docs/getting_started/creating_an_admin.rst index d5e1c8a576..450e653bc2 100644 --- a/docs/getting_started/creating_an_admin.rst +++ b/docs/getting_started/creating_an_admin.rst @@ -5,6 +5,11 @@ You've been able to get the admin interface working in :doc:`the previous chapter `. In this tutorial, you'll learn how to tell SonataAdmin how an admin can manage your models. +.. note:: + This article assumes you are using Symfony 4. Using Symfony 2.8 or 3 + will require to slightly modify some namespaces and paths when creating + entities and admins. + Step 0: Create a Model ---------------------- @@ -14,14 +19,14 @@ using these commands: .. code-block:: bash - $ php bin/console doctrine:generate:entity --entity="AppBundle:Category" --fields="name:string(255)" --no-interaction - $ php bin/console doctrine:generate:entity --entity="AppBundle:BlogPost" --fields="title:string(255) body:text draft:boolean" --no-interaction + $ php bin/console doctrine:generate:entity --entity="App:Category" --fields="name:string(255)" --no-interaction + $ php bin/console doctrine:generate:entity --entity="App:BlogPost" --fields="title:string(255) body:text draft:boolean" --no-interaction After this, you'll need to tweak the entities a bit: .. code-block:: php - // src/AppBundle/Entity/BlogPost.php + // src/Entity/BlogPost.php // ... class BlogPost @@ -50,7 +55,7 @@ Set the default value to ``false``. .. code-block:: php - // src/AppBundle/Entity/BlogPost.php + // src/Entity/BlogPost.php // ... class BlogPost @@ -69,8 +74,7 @@ Set the default value to ``false``. .. code-block:: php - - // src/AppBundle/Entity/Category.php + // src/Entity/Category.php // ... use Doctrine\Common\Collections\ArrayCollection; @@ -105,7 +109,6 @@ After this, create the schema for these entities: $ php bin/console doctrine:schema:create .. note:: - This article assumes you have basic knowledge of the Doctrine2 ORM and you've set up a database correctly. @@ -126,19 +129,20 @@ easiest way to do this is by extending ``Sonata\AdminBundle\Admin\AbstractAdmin` .. code-block:: php - // src/AppBundle/Admin/CategoryAdmin.php - namespace AppBundle\Admin; + // src/Admin/CategoryAdmin.php + namespace App\Admin; use Sonata\AdminBundle\Admin\AbstractAdmin; use Sonata\AdminBundle\Datagrid\ListMapper; use Sonata\AdminBundle\Datagrid\DatagridMapper; use Sonata\AdminBundle\Form\FormMapper; + use Symfony\Component\Form\Extension\Core\Type\TextType; class CategoryAdmin extends AbstractAdmin { protected function configureFormFields(FormMapper $formMapper) { - $formMapper->add('name', 'text'); + $formMapper->add('name', TextType::class); } protected function configureDatagridFilters(DatagridMapper $datagridMapper) @@ -174,18 +178,20 @@ SonataAdminBundle to know that this Admin class exists. To tell the SonataAdminBundle of the existence of this Admin class, you have to create a service and tag it with the ``sonata.admin`` tag: -.. code-block:: yaml +.. configuration-block:: - # app/config/services.yml + .. code-block:: yaml - services: - # ... - admin.category: - class: AppBundle\Admin\CategoryAdmin - arguments: [~, AppBundle\Entity\Category, ~] - tags: - - { name: sonata.admin, manager_type: orm, label: Category } - public: true + # config/services.yaml + + services: + # ... + admin.category: + class: App\Admin\CategoryAdmin + arguments: [~, App\Entity\Category, ~] + tags: + - { name: sonata.admin, manager_type: orm, label: Category } + public: true The constructor of the base Admin class has many arguments. SonataAdminBundle provides a compiler pass which takes care of configuring it correctly for you. @@ -198,15 +204,17 @@ Step 4: Register SonataAdmin custom Routes SonataAdminBundle generates routes for the Admin classes on the fly. To load these routes, you have to make sure the routing loader of the SonataAdminBundle is executed: -.. code-block:: yaml +.. configuration-block:: + + .. code-block:: yaml - # app/config/routing.yml + # config/routing.yaml - # ... - _sonata_admin: - resource: . - type: sonata_admin - prefix: /admin + # ... + _sonata_admin: + resource: . + type: sonata_admin + prefix: /admin View the Category Admin Interface --------------------------------- @@ -216,13 +224,15 @@ how this looks like in the admin interface. Well, let's find out by going to http://localhost:8000/admin .. image:: ../images/getting_started_category_dashboard.png + :align: center + :alt: Sonata Dashboard with Category + :width: 700px Feel free to play around and add some categories, like "Symfony" and "Sonata Project". In the next chapters, you'll create an admin for the ``BlogPost`` entity and learn more about this class. -.. tip:: - +.. note:: If you're not seeing the nice labels, but instead something like "link_add", you should make sure that you've `enabled the translator`_. diff --git a/docs/getting_started/installation.rst b/docs/getting_started/installation.rst index a520af02ce..7ef70781cd 100644 --- a/docs/getting_started/installation.rst +++ b/docs/getting_started/installation.rst @@ -29,7 +29,7 @@ storage bundles. The official storage bundles are: You can download them in the same way as the SonataAdminBundle. Please, choose one and follow its installation instructions before proceeding. -.. tip:: +.. note:: Don't know which to choose? Most new users prefer SonataDoctrineORMAdmin, to interact with traditional relational databases (MySQL, PostgreSQL, etc). @@ -135,7 +135,6 @@ For more information: http://symfony.com/doc/current/translation.html#configurat framework: translator: { fallbacks: ["%locale%"] } - .. note:: If you are not using Symfony Flex, this should be added to ``app/config/config.yml``. diff --git a/docs/getting_started/the_form_view.rst b/docs/getting_started/the_form_view.rst index 6267788a81..f586b4ea05 100644 --- a/docs/getting_started/the_form_view.rst +++ b/docs/getting_started/the_form_view.rst @@ -7,6 +7,11 @@ discover! In the coming chapters, you'll create an Admin class for the more complex ``BlogPost`` model. Meanwhile, you'll learn how to make things a bit more pretty. +.. note:: + This article assumes you are using Symfony 4. Using Symfony 2.8 or 3 + will require to slightly modify some namespaces and paths when creating + entities and admins. + Bootstrapping the Admin Class ----------------------------- @@ -14,8 +19,8 @@ The basic class definition will look the same as the ``CategoryAdmin``: .. code-block:: php - // src/AppBundle/Admin/BlogPostAdmin.php - namespace AppBundle\Admin; + // src/Admin/BlogPostAdmin.php + namespace App\Admin; use Sonata\AdminBundle\Admin\AbstractAdmin; use Sonata\AdminBundle\Datagrid\ListMapper; @@ -43,8 +48,8 @@ The same applies to the service definition: services: # ... admin.blog_post: - class: AppBundle\Admin\BlogPostAdmin - arguments: [~, AppBundle\Entity\BlogPost, ~] + class: App\Admin\BlogPostAdmin + arguments: [~, App\Entity\BlogPost, ~] tags: - { name: sonata.admin, manager_type: orm, label: Blog post } public: true @@ -66,19 +71,22 @@ The ``BlogPost`` model has 4 properties: ``id``, ``title``, ``body``, database. This means the form view just needs 3 fields: title, body and category. -The title and body fields are simple "text" and "textarea" fields, you can add -them straight away: +The title and body fields are simple ``TextType`` and ``TextareaType`` fields, +you can add them straight away: .. code-block:: php - // src/AppBundle/Admin/BlogPostAdmin.php + // src/Admin/BlogPostAdmin.php + + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\TextareaType; // ... protected function configureFormFields(FormMapper $formMapper) { $formMapper - ->add('title', 'text') - ->add('body', 'textarea') + ->add('title', TextType::class) + ->add('body', TextareaType::class) ; } @@ -88,32 +96,35 @@ Adding Fields that Reference Other Models ----------------------------------------- You have a couple different choices on how to add fields that reference other -models. The most basic choice is to use the `entity field type`_ provided by -the DoctrineBundle. This will render a choice field with the available entities -as choice. +models. The most basic choice is to use the ``EntityType`` provided by +the Doctrine Bridge. This will render a choice field with the available +entities as choice. .. code-block:: php - // src/AppBundle/Admin/BlogPostAdmin.php + // src/Admin/BlogPostAdmin.php + + use App\Entity\Category; + use Symfony\Bridge\Doctrine\Form\Type\EntityType; // ... protected function configureFormFields(FormMapper $formMapper) { $formMapper // ... - ->add('category', 'entity', [ - 'class' => 'AppBundle\Entity\Category', - 'property' => 'name', + ->add('category', EntityType::class, [ + 'class' => Category::class, + 'choice_label' => 'name', ]) ; } -.. note:: - - The `property`_ option is not supported by Symfony >= 2.7. You should use `choice_label`_ instead. As each blog post will only have one category, it renders as a select list: .. image:: ../images/getting_started_entity_type.png + :align: center + :alt: Sonata EntityType + :width: 700px When an admin would like to create a new category, they need to go to the category admin page and create a new category. @@ -122,27 +133,33 @@ Using the Sonata Model Type ~~~~~~~~~~~~~~~~~~~~~~~~~~~ To make life easier for admins, you can use the -:ref:`sonata_type_model field type `. This field type will +:ref:`ModelType field `. This field type will also render as a choice field, but it includes a create button to open a dialog with the admin of the referenced model in it: .. code-block:: php - // src/AppBundle/Admin/BlogPostAdmin.php + // src/Admin/BlogPostAdmin.php + + use App\Entity\Category; + use Sonata\AdminBundle\Form\Type\ModelType // ... protected function configureFormFields(FormMapper $formMapper) { $formMapper // ... - ->add('category', 'sonata_type_model', [ - 'class' => 'AppBundle\Entity\Category', + ->add('category', ModelType::class, [ + 'class' => Category::class, 'property' => 'name', ]) ; } .. image:: ../images/getting_started_sonata_model_type.png + :align: center + :alt: Sonata ModelType + :width: 700px Using Groups ------------ @@ -156,20 +173,25 @@ category field to a Meta data group. To do this, use the ``with()`` method: .. code-block:: php - // src/AppBundle/Admin/BlogPostAdmin.php + // src/Admin/BlogPostAdmin.php + + use App\Entity\Category; + use Sonata\AdminBundle\Form\Type\ModelType + use Symfony\Component\Form\Extension\Core\Type\TextType; + use Symfony\Component\Form\Extension\Core\Type\TextareaType; // ... protected function configureFormFields(FormMapper $formMapper) { $formMapper ->with('Content') - ->add('title', 'text') - ->add('body', 'textarea') + ->add('title', TextType::class) + ->add('body', TextareaType::class) ->end() ->with('Meta data') - ->add('category', 'sonata_type_model', [ - 'class' => 'AppBundle\Entity\Category', + ->add('category', ModelType::class, [ + 'class' => Category::class, 'property' => 'name', ]) ->end() @@ -182,7 +204,7 @@ order to tweak the styling: .. code-block:: php - // src/AppBundle/Admin/BlogPostAdmin.php + // src/Admin/BlogPostAdmin.php // ... protected function configureFormFields(FormMapper $formMapper) @@ -200,6 +222,9 @@ order to tweak the styling: This will now result in a much nicer edit page: .. image:: ../images/getting_started_post_edit_grid.png + :align: center + :alt: Sonata edit page + :width: 700px Using Tabs ~~~~~~~~~~ @@ -239,15 +264,14 @@ SonataAdminBundle. You can change it by defining a ``toString()`` method in the Admin class. This receives the object to transform to a string as the first parameter: .. note:: - No underscore prefix! ``toString()`` is correct! .. code-block:: php - // src/AppBundle/Admin/BlogPostAdmin.php + // src/Admin/BlogPostAdmin.php // ... - use AppBundle\Entity\BlogPost; + use App\Entity\BlogPost; class BlogPostAdmin extends AbstractAdmin { diff --git a/docs/getting_started/the_list_view.rst b/docs/getting_started/the_list_view.rst index 8b60f89db8..284dae1143 100644 --- a/docs/getting_started/the_list_view.rst +++ b/docs/getting_started/the_list_view.rst @@ -12,6 +12,11 @@ That's not because there is no content, but because you didn't configure your Admin's list view. As Sonata doesn't know which fields to show, it just shows empty rows. +.. note:: + This article assumes you are using Symfony 4. Using Symfony 2.8 or 3 + will require to slightly modify some namespaces and paths when creating + entities and admins. + Configuring the List Mapper --------------------------- @@ -20,8 +25,8 @@ list page to the list view: .. code-block:: php - // src/AppBundle/Admin/BlogPostAdmin.php - namespace AppBundle\Admin; + // src/Admin/BlogPostAdmin.php + namespace App\Admin; // ... class BlogPostAdmin extends AbstractAdmin @@ -41,6 +46,9 @@ Going to the list view of the blog post admin again, you'll see the available blog posts: .. image:: ../images/getting_started_basic_list_view.png + :align: center + :alt: Sonata list view + :width: 700px You can see that Sonata already guesses a correct field type and makes sure it shows it in a friendly way. The boolean draft field for instance is show as a @@ -60,8 +68,8 @@ instead of ``ListMapper#add()``: .. code-block:: php - // src/AppBundle/Admin/BlogPostAdmin.php - namespace AppBundle\Admin; + // src/Admin/BlogPostAdmin.php + namespace App\Admin; // ... class BlogPostAdmin extends AbstractAdmin @@ -96,8 +104,8 @@ category. .. code-block:: php - // src/AppBundle/Admin/BlogPostAdmin.php - namespace AppBundle\Admin; + // src/Admin/BlogPostAdmin.php + namespace App\Admin; // ... class BlogPostAdmin extends AbstractAdmin @@ -129,8 +137,8 @@ would do something like: .. code-block:: php - // src/AppBundle/Admin/BlogPostAdmin.php - namespace AppBundle\Admin; + // src/Admin/BlogPostAdmin.php + namespace App\Admin; use Sonata\AdminBundle\Datagrid\DatagridMapper; @@ -173,10 +181,12 @@ the search field to use the ``name`` property of the Category: .. code-block:: php - // src/AppBundle/Admin/BlogPostAdmin.php - namespace AppBundle\Admin; + // src/Admin/BlogPostAdmin.php + namespace App\Admin; + use App\Entity\Category; use Sonata\AdminBundle\Datagrid\DatagridMapper; + use Symfony\Bridge\Doctrine\Form\Type\EntityType; // ... class BlogPostAdmin extends AbstractAdmin @@ -185,9 +195,9 @@ the search field to use the ``name`` property of the Category: { $datagridMapper ->add('title') - ->add('category', null, [], 'entity', [ - 'class' => 'AppBundle\Entity\Category', - 'choice_label' => 'name', // In Symfony2: 'property' => 'name' + ->add('category', null, [], EntityType::class, [ + 'class' => Category::class, + 'choice_label' => 'name', ]) ; } @@ -197,6 +207,9 @@ With this code, a dropdown will be shown including all available categories. This will make it easy to filter by category. .. image:: ../images/getting_started_filter_category.png + :align: center + :alt: Sonata Category filter + :width: 700px Round Up --------