跳到内容

列表视图

编辑此页面

本文档将介绍列表视图,您可以使用它来浏览系统中的对象。它将涵盖列表本身的配置以及您可以用来控制可见内容的过滤器。

基本配置

SonataAdmin 选项,可能会影响列表视图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# config/packages/sonata_admin.yaml

sonata_admin:
    templates:
        list:                       '@SonataAdmin/CRUD/list.html.twig'
        action:                     '@SonataAdmin/CRUD/action.html.twig'
        select:                     '@SonataAdmin/CRUD/list__select.html.twig'
        list_block:                 '@SonataAdmin/Block/block_admin_list.html.twig'
        short_object_description:   '@SonataAdmin/Helper/short-object-description.html.twig'
        batch:                      '@SonataAdmin/CRUD/list__batch.html.twig'
        inner_list_row:             '@SonataAdmin/CRUD/list_inner_row.html.twig'
        base_list_field:            '@SonataAdmin/CRUD/base_list_field.html.twig'
        pager_links:                '@SonataAdmin/Pager/links.html.twig'
        pager_results:              '@SonataAdmin/Pager/results.html.twig'

路由

您可以通过删除 Admin 中相应的路由来禁用实体列表。有关路由的更多详细信息,请参阅 路由

1
2
3
4
5
6
7
8
9
10
// src/Admin/PersonAdmin.php

final class PersonAdmin extends AbstractAdmin
{
    protected function configureRoutes(RouteCollectionInterface $collection): void
    {
        // Removing the list route will disable listing entities.
        $collection->remove('list');
    }
}

自定义路由

链接的默认路由是“show”(对于 `FieldDescriptionInterface::TYPE_MANY_TO_ONE` 和 `FieldDescriptionInterface::TYPE_ONE_TO_ONE`)。使用此方法,可以按如下方式自定义路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace App\Admin;

 use Sonata\AdminBundle\Admin\AbstractAdmin;
 use Sonata\AdminBundle\Form\FormMapper;
 use Sonata\AdminBundle\Datagrid\DatagridMapper;
 use Sonata\AdminBundle\Datagrid\ListMapper;
 use Sonata\AdminBundle\Show\ShowMapper;

 final class MediaAdmin extends AbstractAdmin
 {
     protected function configureListFields(ListMapper $list): void
     {
         $list
             ->addIdentifier('field', null, [
                 'route' => [
                     'name' => 'edit'
                 ]
             ]);
     }
}

自定义列表页面上显示的字段

您可以通过 configureListFields 方法自定义列表上显示的列。这是一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// ...

protected function configureListFields(ListMapper $list): void
{
    $list
        // addIdentifier allows to specify that this column
        // will provide a link to the entity
        // (edit or show route, depends on your access rights)
        ->addIdentifier('name')

        // you may specify the field type directly as the
        // second argument instead of in the options
        ->add('isVariation', FieldDescriptionInterface::TYPE_BOOLEAN)

        // if null, the type will be guessed
        ->add('enabled', null, [
            'editable' => true
        ])

        // editable association field
        ->add('status', FieldDescriptionInterface::TYPE_CHOICE, [
            'editable' => true,
            'class' => 'Vendor\ExampleBundle\Entity\ExampleStatus',
            'choices' => [
                1 => 'Active',
                2 => 'Inactive',
                3 => 'Draft',
            ],
        ])

        // editable multiple field
        ->add('winner', FieldDescriptionInterface::TYPE_CHOICE, [
            'editable' => true,
            'multiple' => true,
            'choices' => [
                'jury' => 'Jury',
                'voting' => 'Voting',
                'encouraging' => 'Encouraging',
            ],
        ])

        // we can add options to the field depending on the type
        ->add('price', FieldDescriptionInterface::TYPE_CURRENCY, [
            'currency' => $this->currencyDetector->getCurrency()->getLabel()
        ])

        // Here we specify which property is used to render the label of each entity in the list
        ->add('productCategories', null, [
            'associated_property' => 'name'
            // By default, sorting will be done on the associated property.
            // To sort on another property, add the following:
            'sort_field_mapping' => [
                'fieldName' => 'weight',
            ],
        ])

        // you may also use dotted-notation to access
        // specific properties of a relation to the entity
        ->add('image.name')

        // you may also use a custom accessor
        ->add('description1', null, [
            'accessor' => 'description'
        ])
        ->add('description2', null, [
            'accessor' => function ($subject) {
                return $this->customService->formatDescription($subject);
            }
        ])

        // You may also specify the actions you want to be displayed in the list
        ->add(ListMapper::NAME_ACTIONS, null, [
            'actions' => [
                'show' => [],
                'edit' => [
                    // You may add custom link parameters used to generate the action url
                    'link_parameters' => [
                        'full' => true,
                    ]
                ],
                'delete' => [],
            ]
        ])

    ;
}

提示

编辑和删除操作在默认配置中已启用。您可以添加自己的操作!默认模板文件是:@SonataAdmin/CRUD/list__action_[ACTION_NAME].html.twig

选项

注意

  • (m) 代表 mandatory(必填)
  • (o) 代表 optional(可选)
  • type (m):定义字段类型 - 对于字段描述本身是 mandatory(必填)的,但如果未指定,将尝试自动检测类型
  • template (o):用于渲染字段的模板
  • label (o):用于列标题的名称
  • link_parameters (o):当调用 Admin::generateUrl 时,向相关的 Admin 类添加链接参数
  • code (o):用于检索相关值的方法名称(例如,如果您有一个 array 类型字段,您可能希望显示比 `[0] => 'Value'` 更漂亮的信息;当 getter 不够用时很有用)。注意:适用于类似字符串的类型(string、text、html)
  • associated_property (o):属性路径,用于检索集合元素的“string”表示形式,或以元素作为参数并返回字符串的闭包。
  • sort_field_mapping (o):要排序的集合元素的属性。
  • identifier (o):如果设置为 true,则值上会出现一个链接以编辑元素

可用类型和相关选项

类型 选项 描述
ListMapper::TYPE_ACTIONS 操作 编辑 链接参数 可用操作列表 操作名称(showedithistorydelete 等) 路由参数
ListMapper::TYPE_BATCH   渲染一个复选框
ListMapper::TYPE_SELECT   渲染一个选择框
FieldDescriptionInterface::TYPE_*   参见 字段类型

设置自定义操作按钮

您可以通过设置“template”选项来指定自己的操作按钮,如下所示

1
2
3
4
5
6
7
8
9
$listMapper
    ->add(ListMapper::NAME_ACTIONS, ListMapper::TYPE_ACTIONS, [
        'actions' => [
            'show' => [],
            'edit' => [],
            'delete' => ['template' => 'Admin/MyController/my_partial.html.twig'],
            //this twig file will be located at: templates/Admin/MyController/my_partial.html.twig
        ]
    ]);

Symfony 数据转换器

如果模型字段的值列表有限(枚举),则使用值对象来控制可用值很方便。例如,考虑具有以下值的审核状态值对象:awaitingapprovedrejected

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
final class ModerationStatus
{
    public const AWAITING = 'awaiting';
    public const APPROVED = 'approved';
    public const REJECTED = 'rejected';

    private static $instances = [];

    private string $value;

    private function __construct(string $value)
    {
        if (!array_key_exists($value, self::choices())) {
            throw new \DomainException(sprintf('The value "%s" is not a valid moderation status.', $value));
        }

        $this->value = $value;
    }

    public static function byValue(string $value): ModerationStatus
    {
        // limitation of count object instances
        if (!isset(self::$instances[$value])) {
            self::$instances[$value] = new static($value);
        }

        return self::$instances[$value];
    }

    public function getValue(): string
    {
        return $this->value;
    }

    public static function choices(): array
    {
        return [
            self::AWAITING => 'moderation_status.awaiting',
            self::APPROVED => 'moderation_status.approved',
            self::REJECTED => 'moderation_status.rejected',
        ];
    }

    public function __toString(): string
    {
        return self::choices()[$this->value];
    }
}

要在 _`Symfony Form`: https://symfony.ac.cn/doc/current/forms.html 组件中使用此 Value Object,我们需要 _`Data Transformer`: https://symfony.ac.cn/doc/current/form/data_transformers.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;

final class ModerationStatusDataTransformer implements DataTransformerInterface
{
    public function transform($value): ?string
    {
        $status = $this->reverseTransform($value);

        return $status instanceof ModerationStatus ? $status->value() : null;
    }

    public function reverseTransform($value): ?ModerationStatus
    {
        if (null === $value || '' === $value) {
            return null;
        }

        if ($value instanceof ModerationStatus) {
            return $value;
        }

        try {
            return ModerationStatus::byValue($value);
        } catch (\Throwable $e) {
            throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
        }
    }
}

为了快速审核对象,在查看所有对象的页面上执行此操作很方便。但是,如果我们只是将字段指示为可编辑,那么在编辑时,我们在对象中获得的是具有值本身的字符串(awaitingapprovedrejected),而不是 Value Object (ModerationStatus)。为了解决这个问题,您必须在 data_transformer 字段中指定 Data Transformer,以便它正确地将输入数据转换为您的对象期望的数据

1
2
3
4
5
6
7
8
9
10
11
12
// ...

protected function configureListFields(ListMapper $list): void
{
    $list
        ->add('moderation_status', 'choice', [
            'editable' => true,
            'choices' => ModerationStatus::choices(),
            'data_transformer' => new ModerationStatusDataTransformer(),
        ])
    ;
}

自定义用于生成列表的查询

由于 configureQuery 方法,您可以自定义列表查询

1
2
3
4
5
6
7
8
9
10
11
12
13
protected function configureQuery(ProxyQueryInterface $query): ProxyQueryInterface
{
    $query = parent::configureQuery($query);

    $rootAlias = current($query->getRootAliases());

    $query->andWhere(
        $query->expr()->eq($rootAlias . '.my_field', ':my_param')
    );
    $query->setParameter('my_param', 'my_value');

    return $query;
}

自定义排序顺序

可以通过覆盖 configureDefaultSortValues() 方法来实现配置默认排序列。所有三个键 DatagridInterface::PAGEDatagridInterface::SORT_ORDERDatagridInterface::SORT_BY 都可以省略

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

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridInterface;

final class PostAdmin extends AbstractAdmin
{
    // ...

    protected function configureDefaultSortValues(array &$sortValues): void
    {
        // display the first page (default = 1)
        $sortValues[DatagridInterface::PAGE] = 1;

        // reverse order (default = 'ASC')
        $sortValues[DatagridInterface::SORT_ORDER] = 'DESC';

        // name of the ordered field (default = the model's id field, if any)
        $sortValues[DatagridInterface::SORT_BY] = 'updatedAt';
    }

    // ...
}

注意

DatagridInterface::SORT_BY 键可以是 mySubModel.mySubSubModel.myField 的形式。

注意

出于 UI 原因,无法按多个字段排序。但是,可以通过在 configureQuery() 方法中添加一些默认排序来模拟此行为。以下示例使用 SonataAdminBundleSonataDoctrineORMAdminBundle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// src/Admin/PostAdmin.php

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridInterface;

final class PostAdmin extends AbstractAdmin
{
    // ...

    protected function configureDefaultSortValues(array &$sortValues): void
    {
        // display the first page (default = 1)
        $sortValues[DatagridInterface::PAGE] = 1;

        // reverse order (default = 'ASC')
        $sortValues[DatagridInterface::SORT_ORDER] = 'DESC';

        // name of the ordered field (default = the model's id field, if any)
        $sortValues[DatagridInterface::SORT_BY] = 'updatedAt';
    }

    protected function configureQuery(ProxyQueryInterface $query): ProxyQueryInterface
    {
        $rootAlias = current($query->getRootAliases());

        $query->addOrderBy($rootAlias.'.author', 'ASC');
        $query->addOrderBy($rootAlias.'.createdAt', 'ASC');

        return $query;
    }

    // ...
}

过滤器

您可以添加过滤器,让用户控制将显示哪些数据

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

use Sonata\AdminBundle\Datagrid\DatagridMapper;

final class ClientAdmin extends AbstractAdmin
{
    protected function configureDatagridFilters(DatagridMapper $datagrid): void
    {
        $datagrid
            ->add('phone')
            ->add('email')
        ;
    }

    // ...
}

为了节省空间,所有过滤器默认都是隐藏的。用户必须选中他想要使用的过滤器。

要使过滤器始终可见(即使它处于非活动状态),请将参数 show_filter 设置为 true

1
2
3
4
5
6
7
8
9
10
11
protected function configureDatagridFilters(DatagridMapper $datagrid): void
{
    $datagrid
        ->add('phone')
        ->add('email', null, [
            'show_filter' => true
        ])

        // ...
    ;
}

默认情况下,模板为过滤器生成一个 operator,默认值为 sonata_type_equal。虽然会自动检测到此 operator_type,但可以更改甚至隐藏它

1
2
3
4
5
6
7
8
9
10
11
12
13
protected function configureDatagridFilters(DatagridMapper $datagrid): void
{
    $datagrid
        ->add('foo', null, [
            'operator_type' => 'sonata_type_boolean'
        ])
        ->add('bar', null, [
            'operator_type' => 'hidden'
        ])

        // ...
    ;
}

如果您不需要高级过滤器,或者所有 operator_type 都被隐藏,您可以通过将 advanced_filter 设置为 false 来禁用它们。您需要禁用所有高级过滤器才能使按钮消失

1
2
3
4
5
6
7
8
9
10
11
protected function configureDatagridFilters(DatagridMapper $datagrid): void
{
    $datagrid
        ->add('bar', null, [
            'operator_type' => 'hidden',
            'advanced_filter' => false
        ])

        // ...
    ;
}

默认过滤器

可以使用 configureDefaultFilterValues 方法将默认过滤器添加到 datagrid 值。过滤器具有 value 和可选的 type。如果未给出 type,则使用默认类型 is equal

1
2
3
4
5
6
7
protected function configureDefaultFilterValues(array &$filterValues): void
{
    $filterValues['foo'] = [
        'type'  => ContainsOperatorType::TYPE_CONTAINS,
        'value' => 'bar',
    ];
}

可用类型通过类表示,可以在这里找到。

equalboolean 等类型使用常量将 type 的选择分配给 integer 以作为其 value

1
2
3
4
5
6
7
namespace Sonata\Form\Type;

final class EqualType extends AbstractType
{
    const TYPE_IS_EQUAL = 1;
    const TYPE_IS_NOT_EQUAL = 2;
}

然后,整数将传递到列表操作的 URL 中,例如:/admin/user/user/list?filter[enabled][type]=1&filter[enabled][value]=1

这是一个使用这些常量用于 boolean 类型的示例

1
2
3
4
5
6
7
8
9
10
11
12
13
use Sonata\Form\Type\EqualType;
use Sonata\Form\Type\BooleanType;

final class UserAdmin extends Sonata\UserBundle\Admin\Model\UserAdmin
{
    protected function configureDefaultFilterValues(array &$filterValues): void
    {
        $filterValues['enabled'] = [
            'type'  => EqualType::TYPE_IS_EQUAL, // => 1
            'value' => BooleanType::TYPE_YES     // => 1
        ];
    }
}

请注意,在 boolean 类型上设置 false 值将不起作用,因为该类型期望整数 2 作为类常量中定义的 value

1
2
3
4
5
6
7
namespace Sonata\Form\Type;

final class BooleanType extends AbstractType
{
    const TYPE_YES = 1;
    const TYPE_NO = 2;
}

这种方法允许创建动态过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class PostAdmin extends Sonata\UserBundle\Admin\Model\UserAdmin
{
    protected function configureDefaultFilterValues(array &$filterValues): void
    {
        // Assuming security context injected
        if (!$this->securityContext->isGranted('ROLE_ADMIN')) {
            $user = $this->securityContext->getToken()->getUser();

            $filterValues['author'] = [
                'type'  => EqualType::TYPE_IS_EQUAL,
                'value' => $user->getId()
            ];
        }
    }
}

注意

这不是一种隐藏他人帖子的安全方法。这只是一个按需设置过滤器的示例!

回调过滤器

如果您安装了 SonataDoctrineORMAdminBundle,则可以使用 CallbackFilter 过滤器类型,例如,用于创建全文过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Filter\Model\FilterData;

final class UserAdmin extends Sonata\UserBundle\Admin\Model\UserAdmin
{
    protected function configureDatagridFilters(DatagridMapper $datagrid): void
    {
        $datagrid
            ->add('full_text', CallbackFilter::class, [
                'callback' => [$this, 'getFullTextFilter'],
                'field_type' => TextType::class,
            ]);
    }

    public function getFullTextFilter(ProxyQueryInterface $query, string $alias, string $field, FilterData $data): bool
    {
        if (!$data->hasValue()) {
            return false;
        }

        // Use `andWhere` instead of `where` to prevent overriding existing `where` conditions
        $query->andWhere($query->expr()->orX(
            $query->expr()->like($alias.'.username', $query->expr()->literal('%' . $data->getValue() . '%')),
            $query->expr()->like($alias.'.firstName', $query->expr()->literal('%' . $data->getValue() . '%')),
            $query->expr()->like($alias.'.lastName', $query->expr()->literal('%' . $data->getValue() . '%'))
        ));

        return true;
    }
}

回调函数应返回一个布尔值,指示它是否处于活动状态。

您还可以获取过滤器类型,这有助于更改条件的运算符类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
use Sonata\AdminBundle\Filter\Model\FilterData;
use Sonata\Form\Type\EqualType;

final class UserAdmin extends Sonata\UserBundle\Admin\Model\UserAdmin
{
    public function getFullTextFilter(ProxyQueryInterface $query, string $alias, string $field, FilterData $data): bool
    {
        if (!$data->hasValue()) {
            return false;
        }

        $operator = $data->isType(EqualType::TYPE_IS_EQUAL) ? '=' : '!=';

        $query
            ->andWhere($alias.'.username '.$operator.' :username')
            ->setParameter('username', $data->getValue())
        ;

        return true;
    }
}

可视化配置

您可以配置列表视图以自定义渲染,而无需覆盖整个模板。

以下选项可用

  • `header_style`:自定义标题的样式(宽度、颜色、背景、对齐方式...)
  • `header_class`:自定义标题的类
  • `collapse`:允许使用“阅读更多”链接折叠长文本字段
  • `row_align`:自定义渲染的内部单元格的对齐方式
  • `label_icon`:在标签前添加图标

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protected function configureListFields(ListMapper $list): void
{
    $list
        ->add('id', null, [
            'header_style' => 'width: 5%; text-align: center',
            'row_align' => 'center'
        ])
        ->add('name', FieldDescriptionInterface::TYPE_STRING, [
            'header_style' => 'width: 35%'
        ])
        ->add('description', FieldDescriptionInterface::TYPE_STRING, [
            'header_style' => 'width: 35%',
            'collapse' => true
        ])
        ->add('upvotes', null, [
            'label_icon' => 'fas fa-thumbs-up'
        ])
        ->add('actions', null, [
            'header_class' => 'customActions',
            'row_align' => 'right'
        ])
    ;
}

如果您想自定义 collapse 选项,您还可以提供一个数组来覆盖默认参数

1
2
3
4
5
6
7
8
9
10
11
12
13
->add('description', TextType::class, [
    'header_style' => 'width: 35%',
    'collapse' => [
        // height in px
        'height' => 40,

        // content of the "read more" link
        'more' => 'I want to see the full description',

         // content of the "read less" link
        'less' => 'This text is too long, reduce the size',
    ]
])

如果您只想显示 label_icon

1
2
3
4
->add('upvotes', null, [
    'label' => false,
    'label_icon' => 'fas fa-thumbs-up',
])

马赛克视图按钮

您可以显示/隐藏马赛克视图按钮。

1
2
3
4
5
# config/packages/sonata_admin.yaml

sonata_admin:
    # for hide mosaic view button on all screen using `false`
    show_mosaic_button: true

您可以使用 admin 服务配置显示/隐藏马赛克视图按钮。您需要在您的 admin 服务中添加选项 show_mosaic_button

1
2
3
4
5
6
7
8
9
10
11
# config/services.yaml

sonata_admin.admin.post:
    class: Sonata\AdminBundle\Admin\PostAdmin
    tags:
        - { name: sonata.admin, model_class: Sonata\AdminBundle\Entity\Post, manager_type: orm, group: admin, label: Post, show_mosaic_button: true }

sonata_admin.admin.news:
    class: Sonata\AdminBundle\Admin\NewsAdmin
    tags:
        - { name: sonata.admin, model_class: Sonata\AdminBundle\Entity\News, manager_type: orm, group: admin, label: News, show_mosaic_button: false }

在操作按钮上显示图标

您可以选择列表页面上的操作按钮是显示图标、文本还是两者都显示。

1
2
3
4
5
6
# config/packages/sonata_admin.yaml

sonata_admin:
    options:
        # Choices are: text, icon or all (default)
        list_action_button_content: icon

复选框范围选择

提示

您可以通过单击第一个复选框,然后在按住 Shift 键的同时单击第二个复选框来选中/取消选中一系列复选框。

显示非模型字段

列表视图还可以显示不属于模型类的字段。

在某些情况下,您可以向模型类添加一个新的 getter,以根据模型的其他字段计算字段

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

public function getFullName(): string
{
    return $this->getGivenName().' '.$this->getFamilyName();
}

// src/Admin/UserAdmin.php

protected function configureListFields(ListMapper $list)
{
    $list->addIdentifier('fullName');
}

在模型中数据不可用或让数据库计算值性能更高的情况下,您可以覆盖 configureQuery() Admin 类方法以向结果集添加字段。在 configureListFields() 中,可以使用查询中给定的别名添加这些字段。

在以下示例中,帖子的评论数已添加到查询并显示

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

protected function configureQuery(ProxyQueryInterface $query): ProxyQueryInterface
{
    $query = parent::configureQuery($query);

    $query
        ->leftJoin('n.Comments', 'c')
        ->addSelect('COUNT(c.id) numberofcomments')
        ->addGroupBy('n');

    return $query;
}

protected function configureListFields(ListMapper $list): void
{
    $list->addIdentifier('numberofcomments');
}

最后,您还可以将列表字段定义为 virtual。这样,Sonata 的 FieldDescription 将始终返回 null 值,如此处文档所述:https://docs.sonata-project.org/projects/SonataAdminBundle/en/4.x/cookbook/recipe_virtual_field/

将此与配置自定义模板结合使用,您将拥有一个列表列,其最终渲染内容是完全可自定义的。

1
2
3
4
5
6
7
8
9
// src/Admin/PostAdmin.php

protected function configureListFields(ListMapper $list)
{
    $list->add('thisPropertyDoesNotExist', null, [
        'virtual_field' => true,
        'template' => 'path/to/your/template.html.twig'
    ]);
}

高级用法

显示子模型属性

注意

仅当前缀路径由模型而不是集合组成时,这才有意义。

如果您需要在专用列中仅显示子模型或嵌入式对象的一个字段,则可以简单地使用点分隔表示法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
namespace App\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;

final class UserAdmin extends AbstractAdmin
{
    protected function configureListFields(ListMapper $list): void
    {
        $list
            ->addIdentifier('id')
            ->add('firstName')
            ->add('lastName')
            ->add('address.street')
            ->add('address.ZIPCode')
            ->add('address.town')
        ;
    }
}

自定义模板

如果您需要行单元格的特定布局,则可以定义自定义模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace App\Admin;

 use Sonata\AdminBundle\Admin\AbstractAdmin;
 use Sonata\AdminBundle\FieldDescription\FieldDescriptionInterface;
 use Sonata\AdminBundle\Form\FormMapper;
 use Sonata\AdminBundle\Datagrid\DatagridMapper;
 use Sonata\AdminBundle\Datagrid\ListMapper;
 use Sonata\AdminBundle\Show\ShowMapper;

final class MediaAdmin extends AbstractAdmin
 {
     protected function configureListFields(ListMapper $list): void
     {
         $list
             ->addIdentifier('id')
             ->add('image', FieldDescriptionInterface::TYPE_STRING, ['template' => '@SonataMedia/MediaAdmin/list_image.html.twig'])
             ->add('custom', FieldDescriptionInterface::TYPE_STRING, ['template' => '@SonataMedia/MediaAdmin/list_custom.html.twig'])
         ;
     }
 }

相关模板

1
2
3
4
5
6
7
8
{% extends '@SonataAdmin/CRUD/base_list_field.html.twig' %}

{% block field %}
    <div>
        <strong>{{ object.name }}</strong> <br/>
        {{ object.providername}} : {{ object.width }}x{{ object.height }} <br/>
    </div>
{% endblock %}
这项工作(包括代码示例)已获得 Creative Commons BY-SA 3.0 许可协议的许可。
TOC
    版本