操作
操作 是您可以在 CRUD 页面上执行的每个任务。例如,在 `index
` 页面中,您可以执行“编辑”和“删除”列表中显示的每个实体的任务,以及执行“创建”新实体的另一个任务。
操作在您的 仪表盘 或 CRUD 控制器 的 `configureActions()
` 方法中配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14
namespace App\Controller\Admin;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
class ProductCrudController extends AbstractCrudController
{
// ...
public function configureActions(Actions $actions): Actions
{
// ...
}
}
操作名称和常量
某些方法需要操作名称作为参数。除了使用操作名称的纯字符串(例如 `'index'
`、`'detail'
`、`'edit'
` 等),您还可以使用这些值的常量:`Action::INDEX
`、`Action::DETAIL
`、`Action::EDIT
` 等 (它们在 `EasyCorp
` 类中定义)。
内置操作
以下是每个页面默认包含的内置操作
页面 `
Crud::PAGE_INDEX
` (`'index'
`)- 默认全局添加:`
Action::NEW
` - 默认每个条目添加:`
Action::EDIT
`、`Action::DELETE
` - 每个条目的其他可用操作:`
Action::DETAIL
`
- 默认全局添加:`
页面 `
Crud::PAGE_DETAIL
` (`'detail'
`)- 默认添加:`
Action::EDIT
`、`Action::DELETE
`、`Action::INDEX
` - 其他可用操作:-
- 默认添加:`
页面 `
Crud::PAGE_EDIT
` (`'edit'
`)- 默认添加:`
Action::SAVE_AND_RETURN
`、`Action::SAVE_AND_CONTINUE
` - 其他可用操作:`
Action::DELETE
`、`Action::DETAIL
`、`Action::INDEX
`
- 默认添加:`
页面 `
Crud::PAGE_NEW
` (`'new'
`)- 默认添加:`
Action::SAVE_AND_RETURN
`、`Action::SAVE_AND_ADD_ANOTHER
` - 其他可用操作:`
Action::SAVE_AND_CONTINUE
`、`Action::INDEX
`
- 默认添加:`
添加操作
使用 `add()
` 方法添加任何内置操作以及您自己的自定义操作(将在本文后面解释)
1 2 3 4 5 6 7 8 9 10 11 12
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
public function configureActions(Actions $actions): Actions
{
return $actions
// ...
->add(Crud::PAGE_INDEX, Action::DETAIL)
->add(Crud::PAGE_EDIT, Action::SAVE_AND_ADD_ANOTHER)
;
}
移除操作
移除操作会使其在界面中不可用,因此用户无法单击按钮/链接来运行这些操作。但是,用户可以破解 URL 来运行操作。要完全禁用操作,请使用稍后解释的 `disable()
` 方法
1 2 3 4 5 6 7 8 9 10 11 12
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
public function configureActions(Actions $actions): Actions
{
return $actions
// ...
->remove(Crud::PAGE_INDEX, Action::NEW)
->remove(Crud::PAGE_DETAIL, Action::EDIT)
;
}
更新操作
这主要用于更改内置操作(例如,更改其图标、更新或删除其标签等)。`update()
` 方法需要一个可调用对象作为参数,EasyAdmin 会自动将操作传递给它
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
public function configureActions(Actions $actions): Actions
{
return $actions
// ...
->update(Crud::PAGE_INDEX, Action::NEW, function (Action $action) {
return $action->setIcon('fa fa-file-alt')->setLabel(false);
})
// in PHP 7.4 and newer you can use arrow functions
// ->update(Crud::PAGE_INDEX, Action::NEW,
// fn (Action $action) => $action->setIcon('fa fa-file-alt')->setLabel(false))
;
}
生成动态操作标签
操作标签可以根据与其相关的实体动态生成。例如,`Invoice
` 实体可以通过多次付款进行支付。在每个 `Invoice
` 详细信息页面的顶部,管理员都希望有一个操作链接(或按钮),将其带到一个自定义页面,该页面显示该发票的已收款项。为了提供更好的用户体验,操作链接(或按钮)标签必须显示当前收到的付款数量(即:`3 payments
`)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
public function configureActions(Actions $actions): Actions
{
$viewPayments = Action::new('payments')
->setLabel(function (Invoice $invoice)) {
return \count($invoice->getPayments()) . ' payments';
});
// in PHP 7.4 and newer you can use arrow functions
// ->setLabel(fn (Invoice $invoice) => \count($invoice->getPayments()) . ' payments')
return $actions
// ...
->add(Crud::PAGE_DETAIL, $viewPayments);
}
当相关实体对象不足以计算操作标签时,可以使用任何更具体的服务对象作为委托器。例如,Doctrine 存储库服务对象可用于计算被管理发票的相关付款数量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
private InvoicePaymentRepository $invoicePaymentRepository;
public function __construct(InvoicePaymentRepository $invoicePaymentRepository)
{
$this->invoicePaymentRepository = $invoicePaymentRepository;
}
public function configureActions(Actions $actions): Actions
{
$viewPayments = Action::new('payments')
->setLabel(function (Invoice $invoice)) {
return $this->invoicePaymentRepository->countByInvoice($invoice) . ' payments';
});
return $actions
// ...
->add(Crud::PAGE_DETAIL, $viewPayments);
}
有条件地显示操作
某些操作必须仅在满足某些条件时才显示。例如,只有当订单状态为“已付款”时,才可能显示“查看发票”操作。使用 `displayIf()
` 方法配置操作何时应向用户可见
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
public function configureActions(Actions $actions): Actions
{
$viewInvoice = Action::new('View Invoice', 'fas fa-file-invoice')
->displayIf(static function ($entity) {
return $entity->isPaid();
});
// in PHP 7.4 and newer you can use arrow functions
// ->displayIf(fn ($entity) => $entity->isPaid())
return $actions
// ...
->add(Crud::PAGE_INDEX, $viewInvoice);
}
注意
`displayIf()
` 方法也适用于 全局操作。但是,您的闭包不会接收表示当前实体的对象,因为全局操作不与任何特定实体关联。
禁用操作
禁用操作意味着它不会显示在界面中,即使他们破解 URL,用户也无法运行该操作。如果他们尝试这样做,他们将看到“禁止操作”异常。
操作是全局禁用的,您不能按页面禁用它们
1 2 3 4 5 6 7 8 9 10 11
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
public function configureActions(Actions $actions): Actions
{
return $actions
// ...
// this will forbid to create or delete entities in the backend
->disable(Action::NEW, Action::DELETE)
;
}
限制操作
除了禁用操作外,您还可以限制某些用户执行操作。使用 `setPermission()
` 定义查看和运行某些操作所需的 Symfony Security 权限。
权限是全局定义的;您不能按页面定义不同的权限
1 2 3 4 5 6 7 8 9 10 11
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
public function configureActions(Actions $actions): Actions
{
return $actions
// ...
->setPermission(Action::NEW, 'ROLE_ADMIN')
->setPermission(Action::DELETE, 'ROLE_SUPER_ADMIN')
;
}
重新排序操作
使用 `reorder()
` 定义操作在某些页面中的显示顺序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
public function configureActions(Actions $actions): Actions
{
return $actions
// ...
// you can reorder built-in actions...
->reorder(Crud::PAGE_INDEX, [Action::DETAIL, Action::DELETE, Action::EDIT])
// ...and your own custom actions too
->reorder(Crud::PAGE_INDEX, [Action::DETAIL, 'viewInvoice', Action::DELETE, Action::EDIT])
// you can pass only a few actions to this method and the rest of actions
// will be appended in their original order. In the following example, the
// DELETE and EDIT actions are missing but they will be added automatically
// after DETAIL and 'viewInvoice' actions
->reorder(Crud::PAGE_INDEX, [Action::DETAIL, 'viewInvoice'])
;
}
下拉和内联实体操作
在 `index
` 页面中,实体操作(`edit
`、`delete
` 等)默认显示在下拉列表中。这样做是为了更好地显示每行上的字段内容。如果您希望内联显示所有操作(即,不使用下拉列表),请使用 `showEntityActionsInlined()
` 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
namespace App\Controller\Admin;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
class ProductCrudController extends AbstractCrudController
{
// ...
public function configureCrud(Crud $crud): Crud
{
return $crud
// ...
->showEntityActionsInlined()
;
}
}
添加自定义操作
除了 EasyAdmin 提供的内置操作外,您还可以创建自己的操作。首先,使用 `Action
` 类构造函数定义操作的基本信息(名称、标签、图标)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// the only mandatory argument is the internal name of the action (which is
// used to add the action to some pages, to reorder the action position, etc.)
$viewInvoice = Action::new('viewInvoice');
// the second optional argument is the label visible to end users
$viewInvoice = Action::new('viewInvoice', 'Invoice');
// not defining the label explicitly or setting it to NULL means
// that the label is autogenerated from the name (e.g. 'viewInvoice' -> 'View Invoice')
$viewInvoice = Action::new('viewInvoice', null);
// set the label to FALSE to not display any label for this action (but make sure
// to display an icon for the action; otherwise users can't see or click on the action)
$viewInvoice = Action::new('viewInvoice', false);
// the third optional argument is the icon name
$viewInvoice = Action::new('viewInvoice', 'Invoice', 'fa fa-file-invoice');
默认情况下,EasyAdmin 假定图标名称对应于 FontAwesome CSS 类。必要的 CSS 样式和 Web 字体也默认包含在内,因此您无需执行任何其他步骤即可使用 FontAwesome 图标。或者,您可以使用您自己的图标集而不是 FontAwesome。
然后,您可以配置将表示操作的按钮/元素的基本 HTML/CSS 属性
1 2 3 4 5 6 7 8 9 10 11 12 13
$viewInvoice = Action::new('viewInvoice', 'Invoice', 'fa fa-file-invoice')
// renders the action as a <a> HTML element
->displayAsLink()
// renders the action as a <button> HTML element
->displayAsButton()
// a key-value array of attributes to add to the HTML element
->setHtmlAttributes(['data-foo' => 'bar', 'target' => '_blank'])
// removes all existing CSS classes of the action and sets
// the given value as the CSS class of the HTML element
->setCssClass('btn btn-primary action-foo')
// adds the given value to the existing CSS classes of the action (this is
// useful when customizing a built-in action, which already has CSS classes)
->addCssClass('some-custom-css-class text-danger')
注意
当使用 `setCssClass()
` 或 `addCssClass()
` 方法时,操作将丢失 EasyAdmin 应用的默认 CSS 类(`.btn
` 和 `.action-<the-action-name>
`)。您可能需要手动添加这些 CSS 类,以使您的操作看起来符合预期。
配置基本信息后,使用以下方法之一来定义单击操作时执行的方法
- `
linkToCrudAction()
`:执行当前 CRUD 控制器的某些方法; - `
linkToRoute()
`:通过其路由执行某些常规 Symfony 控制器; - `
linkToUrl()
`:访问外部 URL(当您的操作不是由您的应用程序提供服务时很有用)。
以下示例展示了实践中所有类型的操作
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
namespace App\Controller\Admin;
use App\Entity\Invoice;
use App\Entity\Order;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
class OrderCrudController extends AbstractCrudController
{
// ...
public function configureActions(Actions $actions): Actions
{
// this action executes the 'renderInvoice()' method of the current CRUD controller
$viewInvoice = Action::new('viewInvoice', 'Invoice', 'fa fa-file-invoice')
->linkToCrudAction('renderInvoice');
// if the method is not defined in a CRUD controller, link to its route
$sendInvoice = Action::new('sendInvoice', 'Send invoice', 'fa fa-envelope')
// if the route needs parameters, you can define them:
// 1) using an array
->linkToRoute('invoice_send', [
'send_at' => (new \DateTime('+ 10 minutes'))->format('YmdHis'),
])
// 2) using a callable (useful if parameters depend on the entity instance)
// (the type-hint of the function argument is optional but useful)
->linkToRoute('invoice_send', function (Order $order): array {
return [
'uuid' => $order->getId(),
'method' => $order->getUser()->getPreferredSendingMethod(),
];
});
// this action points to the invoice on Stripe application
$viewStripeInvoice = Action::new('viewInvoice', 'Invoice', 'fa fa-file-invoice')
->linkToUrl(function (Order $entity) {
return 'https://www.stripe.com/invoice/'.$entity->getStripeReference();
});
return $actions
// ...
->add(Crud::PAGE_DETAIL, $viewInvoice)
->add(Crud::PAGE_DETAIL, $sendInvoice)
->add(Crud::PAGE_DETAIL, $viewStripeInvoice)
;
}
public function renderInvoice(AdminContext $context)
{
$order = $context->getEntity()->getInstance();
// add your logic here...
}
}
提示
EasyAdmin 中的 CRUD 控制器扩展了 Symfony 基础控制器类。当操作定义为 CRUD 控制器的方法时,它们可以使用常规 Symfony 控制器 中可用的任何快捷方式和实用程序,例如 `$this->render()
`、`$this->redirect()
` 等。
自定义操作可以定义 `#[AdminAction]
` 属性来自定义其路由名称、路径和方法
1 2 3 4 5 6 7 8 9
use EasyCorp\Bundle\EasyAdminBundle\Attribute\AdminAction;
// ...
#[AdminAction(routePath: '/invoice', routeName: 'view_invoice', methods: ['GET', 'POST'])]
public function renderInvoice(AdminContext $context)
{
// ...
}
全局操作
在列出条目的页面(例如 `Crud::PAGE_INDEX
`)上,您可以配置每个条目的操作以及全局操作。全局操作显示在列出的条目上方。
创建自定义操作并将其全局添加到 `index
` 页面的示例
1 2 3 4 5 6
$goToStripe = Action::new('goToStripe')
->linkToUrl('https://www.stripe.com/')
->createAsGlobalAction()
;
$actions->add(Crud::PAGE_INDEX, $goToStripe);
批量操作
批量操作是一种特殊的操作,它同时应用于多个项目。它们仅在 `index
` 页面中可用。
假设您使用 `User
` 实体管理用户,并且常见的任务是批准他们的注册。与其像前面的章节中解释的那样创建正常的 `approve
` 操作,不如创建一个批量操作以提高效率并一次批准多个用户。
首先,使用 `addBatchAction()
` 方法将其添加到您的操作配置中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
namespace App\Controller\Admin;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
class UserCrudController extends AbstractCrudController
{
// ...
public function configureActions(Actions $actions): Actions
{
return $actions
// ...
->addBatchAction(Action::new('approve', 'Approve Users')
->linkToCrudAction('approveUsers')
->addCssClass('btn btn-primary')
->setIcon('fa fa-user-check'))
;
}
}
批量操作支持与其他操作相同的配置选项,它们可以链接到 CRUD 控制器方法、Symfony 路由或某些 URL。如果至少有一个批量操作,后端界面将更新以添加一些“复选框”,以便可以选择索引列表的多个行。
当用户单击批量操作链接/按钮时,将使用 `POST
` 方法将表单提交到操作或在操作中配置的路由。获取提交数据的最简单方法是使用 `EasyCorp
` 类对批量操作方法的某些参数进行类型提示。如果您这样做,EasyAdmin 将注入一个包含所有批量操作数据的 DTO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
namespace App\Controller\Admin;
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Dto\BatchActionDto;
class UserCrudController extends AbstractCrudController
{
// ...
public function approveUsers(BatchActionDto $batchActionDto)
{
$className = $batchActionDto->getEntityFqcn();
$entityManager = $this->container->get('doctrine')->getManagerForClass($className);
foreach ($batchActionDto->getEntityIds() as $id) {
$user = $entityManager->find($className, $id);
$user->approve();
}
$entityManager->flush();
return $this->redirectToRoute('admin_user_index');
}
}
注意
作为替代方案,除了注入 `BatchActionDto
` 变量外,您还可以注入 Symfony 的 `Request
` 对象以获取所有原始提交的批量数据(例如 `$request->request->all('batchActionEntityIds')
`)。
集成 Symfony 操作
如果操作逻辑很小并且直接与后端相关,则可以将其添加到 CRUD 控制器,因为这大大简化了其在 EasyAdmin 中的集成。但是,有时您的某些逻辑过于复杂或在 Symfony 应用程序的其他部分中使用,因此您无法将其移动到 CRUD 控制器。本节介绍如何将现有的 Symfony 操作集成到 EasyAdmin 中,以便您可以重用后端布局、菜单和其他功能。
假设您的 Symfony 应用程序具有计算有关客户的一些业务统计信息(平均订单金额、年度购买次数等)的操作。所有这些都在 `BusinessStatsCalculator
` 服务中计算,因此您无法创建 CRUD 控制器来显示该信息。相反,创建一个名为 `BusinessStatsController
` 的普通 Symfony 控制器
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
// src/Controller/Admin/BusinessStatsController.php
namespace App\Controller\Admin;
use App\Stats\BusinessStatsCalculator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
#[IsGranted('ROLE_ADMIN')]
class BusinessStatsController extends AbstractController
{
public function __construct(BusinessStatsCalculator $businessStatsCalculator)
{
$this->businessStatsCalculator = $businessStatsCalculator;
}
#[Route("/admin/business-stats", name: "admin_business_stats")]
public function index()
{
return $this->render('admin/business_stats/index.html.twig', [
'data' => $this->businessStatsCalculator->getStatsSummary(),
]);
}
#[Route("/admin/business-stats/{id}", name: "admin_business_stats_customer")]
public function customer(Customer $customer)
{
return $this->render('admin/business_stats/customer.html.twig', [
'data' => $this->businessStatsCalculator->getCustomerStats($customer),
]);
}
}
这是一个普通的 Symfony 控制器(它不扩展任何 EasyAdmin 类),其中包含一些逻辑,用于在 Twig 模板中呈现结果(稍后将显示)。将此控制器集成到您的 EasyAdmin 后端的第一步是使用 `configureMenuItems()
` 方法将其添加到主菜单中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// src/Controller/Admin/DashboardController.php
namespace App\Controller\Admin;
use EasyCorp\Bundle\EasyAdminBundle\Attribute\AdminDashboard;
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
#[AdminDashboard(routePath: '/admin', routeName: 'admin')]
class DashboardController extends AbstractDashboardController
{
// ...
public function configureMenuItems(): iterable
{
// ...
yield MenuItem::linktoRoute('Stats', 'fa fa-chart-bar', 'admin_business_stats');
}
}
如果您重新加载后端并单击该新菜单项,您将看到一个错误,因为 BusinessStatsController 使用的模板尚未创建。查看页面的 URL,您将看到 EasyAdmin 用来集成 Symfony 操作的技巧。
生成的 URL 不是预期的 `/admin/business-stats
` 清晰 URL,而是 `/admin?menuIndex=...&submenuIndex=...&routeName=admin_business_stats
`。这是一个管理 URL,因此 EasyAdmin 可以创建管理上下文,加载适当的菜单等。但是,由于 `routeName
` 查询字符串参数,EasyAdmin 知道它必须将请求转发到为该路由提供服务的 Symfony 控制器,并透明地为您执行此操作。
注意
以这种方式处理路由参数在大多数情况下都很好。但是,有时您需要将路由参数作为正确的 Symfony 路由参数处理。例如,如果您要传递 Symfony 模拟功能的 `_switch_user
` 查询参数,您可以这样做
1 2 3 4 5 6 7 8 9
// you can generate the full URL with Symfony's URL generator:
$impersonate = Action::new('impersonate')->linkToUrl(
$urlGenerator->generate('admin', ['_switch_user' => 'user@example.com'], UrlGeneratorInterface::ABSOLUTE_URL)
);
// or you can add the query string parameter directly:
$impersonate = Action::new('impersonate')
->linkToRoute('some_route')
->setQueryParameter('_switch_user', 'user@example.com');
现在,创建 `index()
` 方法使用的模板,该模板列出了所有客户的统计摘要,并包含指向其中每个客户的详细统计信息的链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
{# templates/admin/business_stats/index.html.twig #}
{% extends '@EasyAdmin/page/content.html.twig' %}
{% block content_title 'Business Stats' %}
{% block main %}
<table>
<thead> {# ... #} </thead>
<tbody>
{% for customer_data in data %}
<tr>
{# ... #}
<td>
<a href="{{ ea_url().setRoute('admin_business_stats_customer', { id: customer_data.id }) }}">
View Details
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
Twig 模板扩展了 EasyAdmin 提供的 内容页面模板,以重用所有后端设计。模板的其余部分是普通的 Twig 代码,除了 URL 生成。您必须使用 ea_url() 函数并传递 Symfony 路由名称和参数,而不是使用 Symfony 的 `path()
` 函数。
与之前发生的情况类似,生成的 URL 不是预期的 `/admin/business-stats/5
`,而是 `/admin?routeName=admin_business_stats_customer&routeParams%5Bid%5D=5
`。但这没关系。EasyAdmin 将运行您的 BusinessStatsController 的 `customer()
` 方法,因此您可以呈现另一个包含客户统计信息的 Twig 模板。
生成集成在 EasyAdmin 中的 Symfony 操作的 URL
如前一节详细解释的那样,在 EasyAdmin 后端集成 Symfony 操作时,您需要以稍微不同的方式生成 URL。您必须使用 EasyAdmin 提供的 AdminUrlGenerator 服务,而不是使用 Symfony 的 UrlGenerator 服务或控制器中的 `$this->generateUrl()
` 快捷方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// src/Controller/SomeController.php
namespace App\Controller;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class SomeController extends AbstractController
{
private $adminUrlGenerator;
public function __construct(AdminUrlGenerator $adminUrlGenerator)
{
$this->adminUrlGenerator = $adminUrlGenerator;
}
public function someMethod()
{
$url = $this->adminUrlGenerator->setRoute('admin_business_stats_customer', [
'id' => $this->getUser()->getId(),
])->generateUrl();
// ...
}
}