diff --git a/Resources/doc/getting_started/creating_an_admin.rst b/Resources/doc/getting_started/creating_an_admin.rst new file mode 100644 index 0000000000..d2c58a26e2 --- /dev/null +++ b/Resources/doc/getting_started/creating_an_admin.rst @@ -0,0 +1,206 @@ +Creating an Admin +================= + +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. + +Step 0: Create a Model +---------------------- + +For the rest of the tutorial, you'll need some sort of model. In this tutorial, +two very simple ``Post`` and ``Tag`` entities will be used. Generate them by +using these commands: + +.. code-block:: bash + + $ php app/console doctrine:generate:entity --entity="AppBundle:Category" --fields="name:string(255)" --no-interaction + $ php app/console doctrine:generate:entity --entity="AppBundle:BlogPost" --fields="title:string(255) body:textdraft:boolean" --no-interaction + +After this, you'll need to tweak the entities a bit: + +.. code-block:: php + + // src/AppBundle/Entity/BlogPost.php + + // ... + class BlogPost + { + // ... + + /** + * @ORM\ManyToOne(targetEntity="Category", inversedBy="blogPosts") + */ + private $category; + + public function setCategory(Category $category) + { + $this->category = $category; + } + + public function getCategory() + { + return $this->category; + } + + // ... + } + +.. code-block:: php + + // src/AppBundle/Entity/Category.php + + // ... + use Doctrine\Common\Collections\ArrayCollection; + // ... + + class Category + { + // ... + + /** + * @ORM\OneToMany(targetEntity="BlogPost", mappedBy="category") + */ + private $blogPosts; + + public function __construct() + { + $this->blogPosts = new ArrayCollection(); + } + + public function getBlogPosts() + { + return $this->blogPosts; + } + + // ... + } + +After this, create the schema for these entities: + +.. code-block:: bash + + $ php app/console doctrine:schema:create + +.. note:: + + This article assumes you have basic knowledge of the Doctrine2 ORM and + you've set up a database correctly. + +Step 1: Create an Admin Class +----------------------------- + +SonataAdminBundle helps you manage your data using a graphical interface that +will let you create, update or search your model instances. The bundle relies +on Admin classes to know which models will be managed and how these actions +will look like. + +An Admin class decides which fields to show on a listing, which fields are used +to find entries and how the create form will look like. Each model will have +its own Admin class. + +Knowing this, let's create an Admin class for the ``Category`` entity. The +easiest way to do this is by extending ``Sonata\AdminBundle\Admin\Admin``. + +.. code-block:: php + + // src/AppBundle/Admin/CategoryAdmin.php + namespace AppBundle\Admin; + + use Sonata\AdminBundle\Admin\Admin; + use Sonata\AdminBundle\Datagrid\ListMapper; + use Sonata\AdminBundle\Datagrid\DatagridMapper; + use Sonata\AdminBundle\Form\FormMapper; + + class CategoryAdmin extends Admin + { + protected function configureFormFields(FormMapper $formMapper) + { + $formMapper->add('name', 'text'); + } + + protected function configureDatagridFilters(DatagridMapper $datagridMapper) + { + $datagridMapper->add('name'); + } + + protected function configureListFields(ListMapper $listMapper) + { + $listMapper->addIdentifier('name'); + } + } + +So, what does this code do? + +* **Line 11-14**: These lines configure which fields are displayed on the edit + and create actions. The ``FormMapper`` behaves similar to the ``FormBuilder`` + of the Symfony Form component; +* **Line 16-19**: This method configures the filters, used to filter and sort + the list of models; +* **Line 21-24**: Here you specify which fields are shown when all models are + listed (the ``addIdentifier()`` method means that this field will link to the + show/edit page of this particular model). + +This is the most basic example of the Admin class. You can configure a lot more +with the Admin class. This will be covered by other, more advanced, articles. + +Step 3: Register the Admin class +-------------------------------- + +You've now created an Admin class, but there is currently no way for the +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 + + # app/config/services.yml + + # ... + services: + admin.category: + class: AppBundle\Admin\CategoryAdmin + arguments: [~, AppBundle\Entity\Category, ~] + tags: + - { name: sonata.admin, manager_type: orm, label: Category } + +The constructor of the base Admin class has many arguments. SonataAdminBundle +provides a compiler pass which takes care of configuring it correctly for you. +You can often tweak things using tag attributes. The code shown here is the +shortest code needed to get it working. + +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 + + # app/config/routing.yml + + # ... + _sonata_admin: + resource: . + type: sonata_admin + prefix: /admin + +View the Category Admin Interface +--------------------------------- + +Now you've created the admin class for your category, you probably want to know +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 + +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:: + + If you're not seeing the nice labels, but instead something like + "link_add", you should make sure that you've `enabled the translator`_. + +.. _`enabled the translator`: http://symfony.com/doc/current/book/translation.html#configuration diff --git a/Resources/doc/getting_started/installation.rst b/Resources/doc/getting_started/installation.rst new file mode 100644 index 0000000000..507c00111a --- /dev/null +++ b/Resources/doc/getting_started/installation.rst @@ -0,0 +1,173 @@ +Installation +============ + +SonataAdminBundle is just a bundle and as such, you can install it at any +moment during a project's lifecycle. + +1. Download the Bundle +---------------------- + +Open a command console, enter your project directory and execute the +following command to download the latest stable version of this bundle: + +.. code-block:: bash + + $ composer require sonata-project/admin-bundle "2.3.*" + +This command requires you to have Composer installed globally, as explained in +the `installation chapter`_ of the Composer documentation. + +1.1. Download a Storage Bundle +------------------------------ + +You've now downloaded the SonataAdminBundle. While this bundle contains all +functionality, it needs storage bundles to be able to communicate with a +database. Before using the SonataAdminBundle, you have to download one of these +storage bundles. The official storage bundles are: + +* `SonataDoctrineORMAdminBundle`_ (integrates the Doctrine ORM); +* `SonataDoctrineMongoDBAdminBundle`_ (integrates the Doctrine MongoDB ODM); +* `SonataPropelAdminBundle`_ (integrates Propel); +* `SonataDoctrinePhpcrAdminBundle`_ (integrates the Doctrine PHPCR ODM). + +You can download them in the same way as the SonataAdminBundle. For instance, +to download the SonataDoctrineORMAdminBundle, execute the following command: + +.. code-block:: bash + + $ composer require sonata-project/doctrine-orm-admin-bundle "2.3.*" + +.. tip:: + + Don't know which to choose? Most new users prefer SonataDoctrineORMAdmin, + to interact with traditional relational databases (MySQL, PostgreSQL, etc). + +Step 2: Enable the Bundle +------------------------- + +Then, enable the bundle and the bundles is relies on by adding the following +line in the `app/AppKernel.php` file of your project: + +.. code-block:: php + + // app/AppKernel.php + + // ... + class AppKernel extends Kernel + { + public function registerBundles() + { + $bundles = array( + // ... + + // The admin requires some twig functions defined in the security + // bundle, like is_granted. Register this bundle if it wasn't the case + // already. + new Symfony\Bundle\SecurityBundle\SecurityBundle(), + + // These are the other bundles the SonataAdminBundle relies on + new Sonata\CoreBundle\SonataCoreBundle(), + new Sonata\BlockBundle\SonataBlockBundle(), + new Knp\Bundle\MenuBundle\KnpMenuBundle(), + + // And finally, the storage and SonataAdminBundle + new Sonata\DoctrineORMAdminBundle\SonataDoctrineORMAdminBundle(), + new Sonata\AdminBundle\SonataAdminBundle(), + ); + + // ... + } + + // ... + } + +.. note:: + + If a bundle is already registered somewhere in your ``AppKernel.php``, you + should not register it again. + +.. note:: + + Since version 2.3, the bundle comes with jQuery and other front-end + libraries. To update the versions (which isn't required), you can use + `Bower`_. To make sure you get the dependencies that match the version of + SonataAdminBundle you are using, you can make bower use the local bower + dependency file, like this: + + .. code-block:: bash + + $ bower install ./vendor/sonata-project/admin-bundle/bower.json + +Step 3: Configure the Installed Bundles +--------------------------------------- + +Now all needed bundles are downloaded and registered, you have to add some +configuration. The admin interface is using SonataBlockBundle to put everything +in blocks. You just have to tell the block bundle about the existence of the +admin block: + +.. code-block:: yaml + + # app/config/config.yml + sonata_block: + default_contexts: [cms] + blocks: + # enable the SonataAdminBundle block + sonata.admin.block.admin_list: + contexts: [admin] + # ... + +.. note:: + + Don't worry too much if, at this point, you don't yet understand fully + what a block is. The SonataBlockBundle is a useful tool, but it's not vital + that you understand it in order to use the admin bundle. + +Step 4: Import Routing Configuration +------------------------------------ + +The bundles are now registered and configured correctly. Before you can use it, +the Symfony router needs to know the routes provided by the SonataAdminBundle. +You can do this by importing them in the routing configuration: + +.. code-block:: yaml + + # app/config/routing.yml + admin_area: + resource: "@SonataAdminBundle/Resources/config/routing/sonata_admin.xml" + prefix: /admin + +Step 5: Preparing your Environment +---------------------------------- + +As with all bundles you install, it's a good practice to clear the cache and +install the assets: + +.. code-block:: bash + + $ php app/console cache:clear + $ php app/console assets:install + +The Admin Interface +------------------- + +You've finished the installation process, congratulations. If you fire up the +server, you can now visit the admin page on http://localhost:8000/admin + +.. note:: + + This tutorial assumes you are using the build-in server using the + ``php app/console server:start`` (or ``server:run``) command. + +.. image:: ../images/getting_started_empty_dashboard.png + +As you can see, the admin panel is very empty. This is because no bundle has +provided admin functionality for the admin bundle yet. Fortunately, you'll +learn how to do this in the :doc:`next chapter `. + +.. _`installation chapter`: https://getcomposer.org/doc/00-intro.md +.. _SonataDoctrineORMAdminBundle: http://sonata-project.org/bundles/doctrine-orm-admin/master/doc/index.html +.. _SonataDoctrineMongoDBAdminBundle: http://sonata-project.org/bundles/mongo-admin/master/doc/index.html +.. _SonataPropelAdminBundle: http://sonata-project.org/bundles/propel-admin/master/doc/index.html +.. _SonataDoctrinePhpcrAdminBundle: http://sonata-project.org/bundles/doctrine-phpcr-admin/master/doc/index.html +.. _Bower: http://bower.io/ diff --git a/Resources/doc/getting_started/the_form_view.rst b/Resources/doc/getting_started/the_form_view.rst new file mode 100644 index 0000000000..daf8e25756 --- /dev/null +++ b/Resources/doc/getting_started/the_form_view.rst @@ -0,0 +1,272 @@ +The Form View +============= + +You've seen the absolute top of the iceberg in +:doc:`the previous chapter `. But there is a lot more to +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. + +Bootstrapping the Admin Class +----------------------------- + +The basic class definition will look the same as the ``CategoryAdmin``: + +.. code-block:: php + + // src/AppBundle/Admin/BlogPostAdmin.php + namespace AppBundle\Admin; + + use Sonata\AdminBundle\Admin\Admin; + use Sonata\AdminBundle\Datagrid\ListMapper; + use Sonata\AdminBundle\Form\FormMapper; + + class BlogPostAdmin extends Admin + { + protected function configureFormFields(FormMapper $formMapper) + { + // ... configure $formMapper + } + + protected function configureListFields(ListMapper $listMapper) + { + // ... configure $listMapper + } + } + +The same applies to the service definition: + +.. code-block:: yaml + + # app/config/services.yml + + # ... + services: + # ... + + admin.blog_post: + class: AppBundle\Admin\BlogPostAdmin + arguments: [~, AppBundle\Entity\BlogPost, ~] + tags: + - { name: sonata.admin, manager_type: orm, label: Blog post } + +Configuring the Form Mapper +--------------------------- + +If you already know the `Symfony Form component`_, the ``FormMapper`` will look +very similar. + +You use the ``add()`` method to add fields to the form. The first argument is +the name of the property the field value maps to, the second argument is the +type of the field (see the `field type reference`_) and the third argument are +additional options to customize the form type. Only the first argument is +required as the Form component has type guessers to guess the type. + +The ``BlogPost`` model has 4 properties: ``id``, ``title``, ``body``, +``category``. The ``id`` property's value is generated automatically by the +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: + +.. code-block:: php + + // src/AppBundle/Admin/BlogPostAdmin.php + + // ... + protected function configureFormFields(FormMapper $formMapper) + { + $formMapper + ->add('title', 'text') + ->add('body', 'textarea') + ; + } + +However, the category field will reference another model. How can you solve that? + +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. + +.. code-block:: php + + // src/AppBundle/Admin/BlogPostAdmin.php + + // ... + protected function configureFormFields(FormMapper $formMapper) + { + $formMapper + // ... + ->add('category', 'entity', array( + 'class' => 'AppBundle\Entity\Category', + 'property' => 'name', + )) + ; + } + +As each blog post will only have one category, it renders as a select list: + +.. image:: ../images/getting_started_entity_type.png + +When an admin would like to create a new category, they need to go to the +category admin page and create a new category. + +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 +also render as a choice field, but it includes a create button to open an +dialog with the admin of the referenced model in it: + +.. code-block:: php + + // src/AppBundle/Admin/BlogPostAdmin.php + + // ... + protected function configureFormFields(FormMapper $formMapper) + { + $formMapper + // ... + ->add('category', 'sonata_type_model', array( + 'class' => 'AppBundle\Entity\Category', + 'property' => 'name', + )) + ; + } + +.. image:: ../images/getting_started_sonata_model_type.png + +Using Groups +------------ + +Currently, everything is put into one block. Since the form only has three +fields, it is still usable, but it can become quite a mess pretty quick. To +solve this, the form mapper also supports grouping fields together. + +For instance, the title and body fields can belong to the Content group and the +category field to a Meta data group. To do this, use the ``with()`` method: + +.. code-block:: php + + // src/AppBundle/Admin/BlogPostAdmin.php + + // ... + protected function configureFormFields(FormMapper $formMapper) + { + $formMapper + ->with('Content') + ->add('title', 'text') + ->add('body', 'textarea') + ->end() + + ->with('Meta data') + ->add('category', 'sonata_type_model', array( + 'class' => 'AppBundle\Entity\Category', + 'property' => 'name', + )) + ->end() + ; + } + +The first argument is the name/label of the group and the second argument is an +array of options. For instance, you can pass HTML classes to the group in +order to tweak the styling: + +.. code-block:: php + + // src/AppBundle/Admin/BlogPostAdmin.php + + // ... + protected function configureFormFields(FormMapper $formMapper) + { + $formMapper + ->with('Content', array('class' => 'col-md-9')) + // ... + ->end() + ->with('Meta data', array('class' => 'col-md-3') + // ... + ->end() + ; + } + +This will now result in a much nicer edit page: + +.. image:: ../images/getting_started_post_edit_grid.png + +Using Tabs +~~~~~~~~~~ + +If you get even more options, you can also use multiple tabs by using the +``tab()`` shortcut method: + +.. code-block:: php + + $formMapper + ->tab('Post') + ->with('Content', ...) + // ... + ->end() + // ... + ->end() + + ->tab('Publish Options') + // ... + ->end() + ; + +Creating a Blog Post +-------------------- + +You've now finished your nice form view for the ``BlogPost`` model. Now it's +time to test it out by creating a post. + +After pressing the "Create" button, you probably see a green message like: +*Item "AppBundle\Entity\BlogPost:00000000192ba93c000000001b786396" has been +successfully created.* + +While it's very friendly of the SonataAdminBundle to notify the admin of a +successful creation, the classname and some sort of hash aren't really nice to +read. This is the default string representation of an object in the +SonataAdminBundle. You can change it by defining a ``toString()`` (note: no +underscore prefix) method in the Admin class. This receives the object to +transform to a string as the first parameter: + +.. code-block:: php + + // src/AppBundle/Admin/BlogPostAdmin.php + + // ... + use AppBundle\Entity\BlogPost; + + class BlogPostAdmin extends Admin + { + // ... + + public function toString($object) + { + return $object instanceof BlogPost + ? $object->getTitle() + : 'Blog Post'; // shown in the breadcrumb on the create view + } + } + +Round Up +-------- + +In this tutorial, you've made your first contact with the greatest feature of +the SonataAdminBundle: Being able to customize literally everything. You've +started by creating a simple form and ended up with a nice edit page for your +admin. + +In the :doc:`next chapter `, you're going to look at the list +and datagrid actions. + +.. _`Symfony Form component`: http://symfony.com/doc/current/book/forms.html +.. _`field type reference`: http://symfony.com/doc/current/reference/forms/types.html +.. _`entity field type`: http://symfony.com/doc/current/reference/forms/types/entity.html diff --git a/Resources/doc/getting_started/the_list_view.rst b/Resources/doc/getting_started/the_list_view.rst new file mode 100644 index 0000000000..9fb4de3068 --- /dev/null +++ b/Resources/doc/getting_started/the_list_view.rst @@ -0,0 +1,215 @@ +The List View +============= + +You've given the admin a nice interface to create and edit blog posts and +categories. But there is not much to change if the admin doesn't have a list of +all available blog posts. Because of this, this chapter will teach you more +about the list view. + +If you have created some posts and go to +http://localhost:8000/admin/app/blogpost/list, you'll see an empty list page. +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. + +Configuring the List Mapper +--------------------------- + +Fixing the above problem is easy: Just add the fields you want to show on the +list page to the list view: + +.. code-block:: php + + // src/AppBundle/Admin/BlogPostAdmin.php + namespace AppBundle\Admin; + + // ... + class BlogPostAdmin extends Admin + { + // ... + + protected function configureListFields(ListMapper $listMapper) + { + $listMapper + ->add('title') + ->add('draft') + ; + } + } + +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 + +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 +red "no" block, indicating ``false``. + +Cool! But... how can an admin go from this page to the edit page for a blog post? +There seem to be nothing that looks like a link. That's correct, you need to +tell Sonata which field(s) you want to use as a link. + +Defining the Identifier Field(s) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The fields which contain a link to the edit pages are called identifier fields. +It makes sense to make the title field link to the edit page, so you can add it +as an identifier field. This is done by using ``ListMapper#addIdentifier()`` +instead of ``ListMapper#add()``: + +.. code-block:: php + + // src/AppBundle/Admin/BlogPostAdmin.php + namespace AppBundle\Admin; + + // ... + class BlogPostAdmin extends Admin + { + // ... + + protected function configureListFields(ListMapper $listMapper) + { + $listMapper + ->addIdentifier('title') + ->add('draft') + ; + } + } + +When saving this, you can now see that the title field has the link you were +looking for. + +Displaying Other Models +~~~~~~~~~~~~~~~~~~~~~~~ + +Now you probably also want the Category to be included in the list. To do that, +you need to reference it. You can't add the ``category`` field to the list +mapper, as it will then try to show the entity as a string. As you've learned +in the previous chapter, adding ``__toString`` to the entity is not recommended +as well. + +Fortunately, there is an easy way to reference other models by using the dot +notation. Using this notation, you can specify which fields you want to show. +For instance, ``category.name`` will show the ``name`` property of the +category. + +.. code-block:: php + + // src/AppBundle/Admin/BlogPostAdmin.php + namespace AppBundle\Admin; + + // ... + class BlogPostAdmin extends Admin + { + // ... + + protected function configureListFields(ListMapper $listMapper) + { + $listMapper + ->addIdentifier('title') + ->add('category.name') + ->add('draft') + ; + } + } + +Adding Filter/Search Options +---------------------------- + +Assume you had a very succesfull blog site containing many blog posts. After a +while, finding the blog post you wanted to edit would be like finding a needle +in a haystack. As with all user experience problems, Sonata provides a solution +for it! + +It does this by allowing you to configure datagrid filters in the +``Admin#configureDatagridFilters()`` method. For instance, to allow the admin +to search blog posts by title (and also order them by alfabet in the list), you +would do something like: + +.. code-block:: php + + // src/AppBundle/Admin/BlogPostAdmin.php + namespace AppBundle\Admin; + + use Sonata\AdminBundle\Datagrid\DatagridMapper; + + // ... + class BlogPostAdmin extends Admin + { + protected function configureDatagridFilters(DatagridMapper $datagridMapper) + { + $datagridMapper->add('title'); + } + } + +This will add a little block to the left of the block showing a search input +for the title field. + +Filtering by Category +~~~~~~~~~~~~~~~~~~~~~ + +Filtering by another model's properties is a little bit more difficult. The add +field has 5 arguments: + +.. code-block:: php + + public function add( + $name, + + // filter + $type = null, + array $filterOptions = array(), + + // field + $fieldType = null, + $fieldOptions = null + ) + +As you can see, you can both customize the type used to filter and the type +used to display the search field. You can rely on the type guessing mechanism +of Sonata to pick the correct field types. However, you still need to configure +the search field to use the ``name`` property of the Category: + +.. code-block:: php + + // src/AppBundle/Admin/BlogPostAdmin.php + namespace AppBundle\Admin; + + use Sonata\AdminBundle\Datagrid\DatagridMapper; + + // ... + class BlogPostAdmin extends Admin + { + protected function configureDatagridFilters(DatagridMapper $datagridMapper) + { + $datagridMapper + ->add('title'); + ->add('category', null, array(), 'entity', array( + 'class' => 'AppBundle\Entity\Category', + 'property' => 'name', + )) + ; + } + } + +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 + +Round Up +-------- + +This time, you've learned how to make it easy to find posts to edit. You've +learned how to create a nice list view and how to add options to search, order +and filter this list. + +There might have been some very difficult things, but imagine the difficulty +writing everything yourself! As you're now already quite good with the basics, +you can start reading other articles in the documentation, like: + +* :doc:`Customizing the Dashboard <../reference/dashboard>` +* :doc:`Configuring the Security system <../reference/security>` +* :doc:`Adding export functionality <../reference/action_export>` +* :doc:`Adding a preview page <../reference/preview_mode>` diff --git a/Resources/doc/images/getting_started_basic_list_view.png b/Resources/doc/images/getting_started_basic_list_view.png new file mode 100644 index 0000000000..eadbfe1066 Binary files /dev/null and b/Resources/doc/images/getting_started_basic_list_view.png differ diff --git a/Resources/doc/images/getting_started_category_dashboard.png b/Resources/doc/images/getting_started_category_dashboard.png new file mode 100644 index 0000000000..b4676889ec Binary files /dev/null and b/Resources/doc/images/getting_started_category_dashboard.png differ diff --git a/Resources/doc/images/getting_started_empty_dashboard.png b/Resources/doc/images/getting_started_empty_dashboard.png new file mode 100644 index 0000000000..1a02bddca1 Binary files /dev/null and b/Resources/doc/images/getting_started_empty_dashboard.png differ diff --git a/Resources/doc/images/getting_started_entity_type.png b/Resources/doc/images/getting_started_entity_type.png new file mode 100644 index 0000000000..25e5568ca0 Binary files /dev/null and b/Resources/doc/images/getting_started_entity_type.png differ diff --git a/Resources/doc/images/getting_started_filter_category.png b/Resources/doc/images/getting_started_filter_category.png new file mode 100644 index 0000000000..4774919a24 Binary files /dev/null and b/Resources/doc/images/getting_started_filter_category.png differ diff --git a/Resources/doc/images/getting_started_post_edit_grid.png b/Resources/doc/images/getting_started_post_edit_grid.png new file mode 100644 index 0000000000..14a3bcb317 Binary files /dev/null and b/Resources/doc/images/getting_started_post_edit_grid.png differ diff --git a/Resources/doc/images/getting_started_sonata_model_type.png b/Resources/doc/images/getting_started_sonata_model_type.png new file mode 100644 index 0000000000..a9e51baa97 Binary files /dev/null and b/Resources/doc/images/getting_started_sonata_model_type.png differ diff --git a/Resources/doc/index.rst b/Resources/doc/index.rst index da907f522a..2bc18c68f6 100644 --- a/Resources/doc/index.rst +++ b/Resources/doc/index.rst @@ -11,6 +11,18 @@ Admin Bundle The demo website can be found in http://demo.sonata-project.org/admin/dashboard (``admin`` as user and password). +Getting Started +--------------- + +.. toctree:: + :maxdepth: 1 + :numbered: + + getting_started/installation + getting_started/creating_an_admin + getting_started/the_form_view + getting_started/the_list_view + Reference Guide --------------- diff --git a/Resources/doc/reference/form_types.rst b/Resources/doc/reference/form_types.rst index df6ad3af11..6c5791540b 100644 --- a/Resources/doc/reference/form_types.rst +++ b/Resources/doc/reference/form_types.rst @@ -9,6 +9,8 @@ When defining fields in your Admin classes you can use any of the standard there are some special Sonata field types which allow you to work with relationships between one entity class and another. +.. _field-types-model: + sonata_type_model ^^^^^^^^^^^^^^^^^