Skip to content
  • About
    • What is Symfony?
    • Community
    • News
    • Contributing
    • Support
  • Documentation
    • Symfony Docs
    • Symfony Book
    • Screencasts
    • Symfony Bundles
    • Symfony Cloud
    • Training
  • Services
    • Platform.sh for Symfony Best platform to deploy Symfony apps
    • SymfonyInsight Automatic quality checks for your apps
    • Symfony Certification Prove your knowledge and boost your career
    • SensioLabs Professional services to help you with Symfony
    • Blackfire Profile and monitor performance of your apps
  • Other
  • Blog
  • Download
sponsored by
  1. Home
  2. Documentation
  3. Bundles
  4. SonataAdminBundle
  5. The Form View

The Form View

Edit this page

You've seen the absolute top of the iceberg in 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// src/Admin/BlogPostAdmin.php

namespace App\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;

final class BlogPostAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $form): void
    {
        // ... configure $form
    }

    protected function configureListFields(ListMapper $list): void
    {
        // ... configure $list
    }
}

The same applies to the service definition:

1
2
3
4
5
6
7
# config/services.yaml

services:
    admin.blog_post:
        class: App\Admin\BlogPostAdmin
        tags:
            - { name: sonata.admin, model_class: App\Entity\BlogPost, 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 needs 3 fields: title, body and category.

The title and body fields are TextType and TextareaType fields, you can add them straight away:

1
2
3
4
5
6
7
8
9
10
11
12
// src/Admin/BlogPostAdmin.php

use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;

protected function configureFormFields(FormMapper $form): void
{
    $form
        ->add('title', TextType::class)
        ->add('body', TextareaType::class)
    ;
}

However, the category field will reference another model. How can you solve that?

Adding Fields that Reference Other Models

Using the Entity Type

You have a couple different choices on how to add fields that reference other 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// src/Admin/BlogPostAdmin.php

use App\Entity\Category;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;

protected function configureFormFields(FormMapper $form): void
{
    $form
        // ...
        ->add('category', EntityType::class, [
            'class' => Category::class,
            'choice_label' => 'name',
        ])
    ;
}

As each blog post will only have one category, it renders as a select list:

Sonata EntityType

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 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// src/Admin/BlogPostAdmin.php

use App\Entity\Category;
use Sonata\AdminBundle\Form\Type\ModelType;

protected function configureFormFields(FormMapper $form): void
{
    $form
        ->add('category', ModelType::class, [
            'class' => Category::class,
            'property' => 'name',
        ])
    ;
}
Sonata ModelType

Using Groups and Tabs

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 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 $form): void
{
    $form
        ->with('Content')
            ->add('title', TextType::class)
            ->add('body', TextareaType::class)
        ->end()
        ->with('Meta data')
            ->add('category', ModelType::class, [
                'class' => Category::class,
                '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:

1
2
3
4
5
6
7
8
9
10
11
12
13
// src/Admin/BlogPostAdmin.php

protected function configureFormFields(FormMapper $form): void
{
    $form
        ->with('Content', ['class' => 'col-md-9'])
            // ...
        ->end()
        ->with('Meta data', ['class' => 'col-md-3'])
            // ...
        ->end()
    ;
}

This will now result in a much nicer edit page:

Sonata edit page

Using Tabs

If you get even more options, you can also use multiple tabs by using the tab() shortcut method:

1
2
3
4
5
6
7
8
9
10
11
12
$form
    ->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 "AppEntityBlogPost: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() method in the Admin class. This receives the object to transform to a string as the first parameter:

1
2
3
4
5
6
7
8
9
10
11
12
13
// src/Admin/BlogPostAdmin.php

use App\Entity\BlogPost;

final class BlogPostAdmin extends AbstractAdmin
{
    public function toString(object $object): string
    {
        return $object instanceof BlogPost
            ? $object->getTitle()
            : 'Blog Post'; // shown in the breadcrumb on the create view
    }
}

Note

No underscore prefix! toString() is correct!

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 form and ended up with a nice edit page for your admin.

In the next chapter, you're going to look at the list and datagrid actions.

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version
    Measure & Improve Symfony Code Performance

    Measure & Improve Symfony Code Performance

    Become certified from home

    Become certified from home

    Version:

    Table of Contents

    • Bootstrapping the Admin Class
    • Configuring the Form Mapper
    • Adding Fields that Reference Other Models
      • Using the Entity Type
      • Using the Sonata Model Type
    • Using Groups and Tabs
      • Using Groups
      • Using Tabs
    • Creating a Blog Post
    • Round Up

    Symfony footer

    Avatar of alexmart, a Symfony contributor

    Thanks alexmart for being a Symfony contributor

    1 commit • 181 lines changed

    View all contributors that help us make Symfony

    Become a Symfony contributor

    Be an active part of the community and contribute ideas, code and bug fixes. Both experts and newcomers are welcome.

    Learn how to contribute

    Symfony™ is a trademark of Symfony SAS. All rights reserved.

    • What is Symfony?

      • What is Symfony?
      • Symfony at a Glance
      • Symfony Components
      • Symfony Releases
      • Security Policy
      • Logo & Screenshots
      • Trademark & Licenses
      • symfony1 Legacy
    • Learn Symfony

      • Symfony Docs
      • Symfony Book
      • Reference
      • Bundles
      • Best Practices
      • Training
      • eLearning Platform
      • Certification
    • Screencasts

      • Learn Symfony
      • Learn PHP
      • Learn JavaScript
      • Learn Drupal
      • Learn RESTful APIs
    • Community

      • Symfony Community
      • SymfonyConnect
      • Events & Meetups
      • Projects using Symfony
      • Contributors
      • Symfony Jobs
      • Backers
      • Code of Conduct
      • Downloads Stats
      • Support
    • Blog

      • All Blog Posts
      • A Week of Symfony
      • Case Studies
      • Cloud
      • Community
      • Conferences
      • Diversity
      • Living on the edge
      • Releases
      • Security Advisories
      • Symfony Insight
      • Twig
      • SensioLabs Blog
    • Services

      • SensioLabs services
      • Train developers
      • Manage your project quality
      • Improve your project performance
      • Host Symfony projects

      Powered by

    Follow Symfony