路由
CRUD 控制器中使用的默认路由可以通过 Admin
类访问。
Admin
类包含两个路由方法
getRoutes()
: 返回可用的路由;generateUrl($name, $options)
: 生成相关的路由。
路由定义
路由名称
你可以重写 Admin
类中的 generateBaseRouteName()
方法。这表示路由前缀,实际的路由名称将通过在该前缀后添加下划线和操作名称来生成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// src/Admin/PostAdmin.php
final class PostAdmin extends AbstractAdmin
{
protected function generateBaseRouteName(bool $isChildAdmin = false): string
{
return 'sonata_post';
}
// will result in routes named:
// sonata_post_list
// sonata_post_create
// etc..
// ...
}
注意
这是路由的内部名称(与路由可见的 URL 无关)。
默认情况下,Admin 将根据以下格式为你生成路由名称:'admin_vendor_bundlename_entityname',因此你的操作将拥有类似 'admin_vendor_bundlename_entityname_list' 的路由名称。
如果 Admin 无法为你的 Admin 类找到 baseRouteName
,将抛出一个带有相关信息的 RuntimeException
。
如果 admin 类是另一个 admin 类的子类,路由名称将以父路由名称为前缀,例如
1 2 3 4 5 6 7 8 9 10
// src/Admin/PostAdmin.php
// The parent admin class
final class PostAdmin extends AbstractAdmin
{
protected function generateBaseRouteName(bool $isChildAdmin = false): string
{
return 'sonata_post';
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// src/Admin/CommentAdmin.php
// The child admin class
final class CommentAdmin extends AbstractAdmin
{
protected function generateBaseRouteName(bool $isChildAdmin = false): string
{
return 'comment';
}
// will result in routes named :
// sonata_post_comment_list
// sonata_post_comment_create
// etc..
// ...
}
路由模式 (URL)
你可以重写 generateBaseRoutePattern()
方法来为给定的 Admin
类设置自定义 URL。
例如,要将 http://yourdomain.com/admin/foo
用作 FooAdmin
类的基本 URL(而不是默认的 http://yourdomain.com/admin/vendor/bundle/foo
),请使用以下代码
1 2 3 4 5 6 7 8 9
// src/Admin/FooAdmin.php
final class FooAdmin extends AbstractAdmin
{
protected function generateBaseRoutePattern(bool $isChildAdmin = false): string
{
return 'foo';
}
}
然后你将拥有像 http://yourdomain.com/admin/foo/list
和 http://yourdomain.com/admin/foo/1/edit
这样的路由 URL
如果 admin 类是另一个 admin 类的子类,路由模式将以父路由模式为前缀,例如
1 2 3 4 5 6 7 8 9 10 11
// src/Admin/PostAdmin.php
// The parent admin class
final class PostAdmin extends AbstractAdmin
{
protected function generateBaseRoutePattern(bool $isChildAdmin = false): string
{
return 'post';
}
// ...
}
1 2 3 4 5 6 7 8 9 10 11
// src/Admin/CommentAdmin.php
// The child admin class
final class CommentAdmin extends AbstractAdmin
{
protected function generateBaseRoutePattern(bool $isChildAdmin = false): string
{
return 'comment';
}
// ...
}
对于 comment,你将拥有像 http://yourdomain.com/admin/post/{postId}/comment/list
和 http://yourdomain.com/admin/post/{postId}/comment/{commentId}/edit
这样的路由 URL
路由用法
在 CRUD 模板中,当前 Admin
类的路由可以通过 admin 变量的 generateUrl()
命令生成
1
<a href="{{ admin.generateUrl('list') }}">List</a>
1
<a href="{{ admin.generateUrl('list', params|merge({'page': 1})) }}">List</a>
请注意,你不需要提供 Admin 的路由前缀 (baseRouteName
) 来为当前 Admin 生成 URL,只需要操作名称。
要为不同的 Admin 生成 URL,请使用路由名称调用 Symfony Twig 函数 path
1
<a href="{{ path('admin_app_post_list') }}">Post List</a>
创建路由
你可以通过在 Admin
类中定义新路由来注册它们。只有 Admin 路由应该以这种方式注册。
你以这种方式定义的路由是在你的 Admin 上下文中生成的,并且 add()
唯一必需的参数是操作名称。第二个参数可以用于定义要附加到 baseRoutePattern
的 URL 格式,如果未显式设置,则默认为操作名称
1 2 3 4 5 6 7 8 9 10 11 12
// src/Admin/MediaAdmin.php
use Sonata\AdminBundle\Route\RouteCollectionInterface;
final class MediaAdmin extends AbstractAdmin
{
protected function configureRoutes(RouteCollectionInterface $collection): void
{
$collection->add('myCustom'); // Action gets added automatically
$collection->add('view', $this->getRouterIdParameter().'/view');
}
}
使用所有路由参数
由于 add
方法创建了一个 Symfony Route
,你可以使用 Route
的所有构造函数参数作为 add
方法的参数来设置其他设置,就像这样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// src/Admin/MediaAdmin.php
use Sonata\AdminBundle\Route\RouteCollectionInterface;
final class MediaAdmin extends AbstractAdmin
{
protected function configureRoutes(RouteCollectionInterface $collection): void
{
$collection->add(
'custom_action',
$this->getRouterIdParameter().'/custom-action',
[],
[],
[],
'',
['https'],
['GET', 'POST']
);
}
}
创建新操作所需的其他步骤
除了为你的新操作定义路由外,你还需要在你的控制器中为其创建一个处理程序。默认情况下,Admin 类使用 Sonata\AdminBundle\Controller\CRUDController
作为它们的控制器,但这可以通过在定义你的 Admin 服务时更改第三个参数来更改。
例如,让我们将我们的 MediaAdmin 类的控制器更改为 App\Controller\MediaCRUDController
1 2 3 4 5 6
# config/services.yaml
app.admin.media:
class: App\Admin\MediaAdmin
tags:
- { name: sonata.admin, model_class: App\Entity\Page, controller: App\Controller\MediaCRUDController, manager_type: orm, label: 'Media' }
现在我们需要创建我们的控制器,最简单的方法是扩展基本的 Sonata CRUD 控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// src/Controller/MediaCRUDController.php
namespace App\Controller;
use Sonata\AdminBundle\Controller\CRUDController;
use Symfony\Component\HttpFoundation\Response;
class MediaCRUDController extends CRUDController
{
public function myCustomAction(): Response
{
// your code here ...
}
}
移除路由
扩展 Sonata\AdminBundle\Admin\AbstractAdmin
将为你的 Admin 类提供以下默认路由
- 批量
- 创建
- 删除
- 导出
- 编辑
- 列表
- 显示
你可以使用控制台运行以下命令来查看为 Admin 类定义的所有当前路由
1
bin/console sonata:admin:explain <<admin.service.name>>
例如,如果你的 Admin 被调用 sonata.admin.foo,你将运行
1
bin/console sonata:admin:explain app.admin.foo
Sonata 在链接到路由之前会在内部检查路由是否存在。因此,删除路由将阻止指向该操作的链接出现在管理界面中。例如,删除 'create' 路由将阻止任何指向 “添加新项” 的链接出现。
移除单个路由
任何单个注册的路由都可以通过名称移除
1 2 3 4 5 6 7 8 9 10 11
// src/Admin/MediaAdmin.php
use Sonata\AdminBundle\Route\RouteCollectionInterface;
final class MediaAdmin extends AbstractAdmin
{
protected function configureRoutes(RouteCollectionInterface $collection): void
{
$collection->remove('delete');
}
}
移除除命名路由外的所有路由
如果你想禁用除少数允许的路由之外的所有默认 Sonata 路由,你可以使用 clearExcept()
方法。此方法接受一个你想保持激活状态的路由数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// src/Admin/MediaAdmin.php
use Sonata\AdminBundle\Route\RouteCollectionInterface;
final class MediaAdmin extends AbstractAdmin
{
protected function configureRoutes(RouteCollectionInterface $collection): void
{
// Only `list` and `edit` route will be active
$collection->clearExcept(['list', 'edit']);
// You can also pass a single string argument
$collection->clearExcept('list');
}
}
移除所有路由
如果你想移除所有默认路由,你可以使用 clear()
方法
1 2 3 4 5 6 7 8 9 10 11 12
// src/Admin/MediaAdmin.php
use Sonata\AdminBundle\Route\RouteCollectionInterface;
final class MediaAdmin extends AbstractAdmin
{
protected function configureRoutes(RouteCollectionInterface $collection): void
{
// All routes are removed
$collection->clear();
}
}
仅当嵌入 Admin 时移除路由
为了防止当一个 Admin 嵌入到另一个 Admin 中时某些路由可用(例如,当你在 PostAdmin 中嵌入 TagAdmin 时移除 “添加新项” 选项),你可以使用 hasParentFieldDescription()
来检测这种情况并移除路由
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// src/Admin/TagAdmin.php
use Sonata\AdminBundle\Route\RouteCollectionInterface;
final class TagAdmin extends AbstractAdmin
{
protected function configureRoutes(RouteCollectionInterface $collection): void
{
// prevent display of "Add new" when embedding this form
if ($this->hasParentFieldDescription()) {
$collection->remove('create');
}
}
}
恢复单个路由
任何先前移除的路由都可以通过名称恢复
1 2 3 4 5 6 7 8 9 10 11
// src/Admin/DeletableMediaAdmin.php
use Sonata\AdminBundle\Route\RouteCollectionInterface;
final class DeletableMediaAdmin extends MediaAdmin
{
protected function configureRoutes(RouteCollectionInterface $collection): void
{
$collection->restore('delete');
}
}
持久参数
在某些情况下,可能需要在不同的 Admin
操作之间传递相同的参数。与其在模板中设置它们或进行其他奇怪的 hack,不如定义一个 configurePersistentParameters()
方法。此方法将在生成链接时使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// src/Admin/MediaAdmin.php
final class MediaAdmin extends AbstractAdmin
{
protected function configurePersistentParameters(): array
{
if (!$this->getRequest()) {
return [];
}
return [
'provider' => $this->getRequest()->get('provider'),
'context' => $this->getRequest()->get('context', 'default'),
];
}
}
如果你在某处调用 $admin->generateUrl('create')
,则生成的 URL 如下所示: /admin/module/create?context=default
在列表操作中更改默认路由
通常,列表操作的标识符列链接到编辑屏幕。要更改列表操作的链接以指向不同的操作,请在调用 ListMapper::addIdentifier()
时设置 route
选项。例如,链接到 show 而不是 edit
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// src/Admin/PostAdmin.php
final class PostAdmin extends AbstractAdmin
{
protected function configureListFields(ListMapper $list): void
{
$list
->addIdentifier('name', null, [
'route' => [
'name' => 'show'
]
]);
}
}