列表视图
本文档将介绍列表视图,您可以使用它来浏览系统中的对象。它将涵盖列表本身的配置以及您可以用来控制可见内容的过滤器。
基本配置
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 |
操作 编辑 链接参数 | 可用操作列表 操作名称(show 、edit 、history 、delete 等) 路由参数 |
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 数据转换器
如果模型字段的值列表有限(枚举),则使用值对象来控制可用值很方便。例如,考虑具有以下值的审核状态值对象:awaiting
、approved
、rejected
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);
}
}
}
为了快速审核对象,在查看所有对象的页面上执行此操作很方便。但是,如果我们只是将字段指示为可编辑,那么在编辑时,我们在对象中获得的是具有值本身的字符串(awaiting
、approved
、rejected
),而不是 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::PAGE
、DatagridInterface::SORT_ORDER
和 DatagridInterface::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()
方法中添加一些默认排序来模拟此行为。以下示例使用 SonataAdminBundle
和 SonataDoctrineORMAdminBundle
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',
];
}
可用类型通过类表示,可以在这里找到。
equal
和 boolean
等类型使用常量将 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 %}