跳到内容

路由

编辑此页

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/listhttp://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/listhttp://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'
                ]
            ]);
    }
}
本作品,包括代码示例,根据 Creative Commons BY-SA 3.0 许可协议获得许可。
目录
    版本