我们将 SonataAdminBundle 与 Symfony2 应用程序一起使用。编辑实体时,我想将自己的操作添加到位于右上角的下拉菜单中,但我不知道这是如何工作的。
我知道我可以通过添加自己的路由configureRoutes(RouteCollection $collection)
以及如何添加批处理操作或在列表视图中的实体后面添加自己的操作,但是如何在编辑视图的操作下拉列表中添加自己的链接?
它基本上只是像“在前端显示这个实体”这样的链接,所以不需要大逻辑。
一种方法是覆盖编辑时使用的模板。现在,您需要做的是:
app/Resources
在调用中创建新目录(如果您还没有)SonataAdminBundle
。在里面,创建另一个名为views
. 这将创建一个类似的路径app/Resources/SonataAdminBundle/views
。这是 Symfony 的基本模板覆盖。您可以在此处阅读有关该主题的更多信息。
现在,您应该按照与原始包中相同的路径复制原始模板。我们这里感兴趣的模板文件位于sonata-project/admin-bundle/Resources/views/CRUD/base_edit.html.twig
. 这意味着您必须在其中创建另一个文件夹views
(我们刚刚在 中创建的文件夹app
,称为CRUD
。所以,现在我们必须遵循路径app/Resources/SonataAdminBundle/views/CRUD
。将模板(base_edit.html.twig
)粘贴到其中,我们可以开始编辑。
请记住,您拥有的每个编辑操作都会使用以下模板。因此,是否要在每个 edit_action 中显示该链接取决于您。我将向您展示一种限制特定操作的方法。
您要编辑的块{% block actions %}
负责渲染下拉菜单。这就是它现在的样子:
{% block actions %}
<li>{% include 'SonataAdminBundle:Button:show_button.html.twig' %}</li>
<li>{% include 'SonataAdminBundle:Button:history_button.html.twig' %}</li>
<li>{% include 'SonataAdminBundle:Button:acl_button.html.twig' %}</li>
<li>{% include 'SonataAdminBundle:Button:list_button.html.twig' %}</li>
<li>{% include 'SonataAdminBundle:Button:create_button.html.twig' %}</li>
{% endblock %}
现在剩下要做的就是在最后一个<li>
标签之后插入您的链接。
{% if admin.id(object) is not null and app.request.get('_route') == 'my_route' %}
<li>
<a href="/generate/path/with/your/route">View in Frontend</a>
</li>
{% endif %}
admin.id(object)
将返回您编辑的项目的当前 ID。app.request.get('_route')
将返回您的编辑操作的路线。如果您希望您的链接显示在所有编辑操作中,您可以删除它。使用更改<a href="/generate/path/with/your/route">View in Frontend</a>
您的路线名称admin.id(object)
,您应该一切顺利。
在您的管理类中,覆盖以下方法:
public function getActionButtons($action, $object = null)
{
$list = parent::getActionButtons($action, $object);
$list['upload'] = [
'template' => ':admin:my_upload_button.html.twig',
];
return $list;
}
这将在此管理员的所有页面上添加一个自定义操作按钮。您可以在此处添加任何逻辑来决定$action
要在哪些页面 (-s) 上显示按钮。
您可以在模板中做您想做的事,但只是为了完成我的示例并显示与我的自定义操作的连接:
<li>
<a class="sonata-action-element" href="{{ admin.generateUrl('upload') }}">
<i class="fa fa-cloud-upload" aria-hidden="true"></i>
Upload stuff
</a>
</li>
另一种方法是覆盖generateObjectUrl()
对象管理类中的方法。
/**
* @see \Sonata\AdminBundle\Admin\Admin::generateObjectUrl()
*/
public function generateObjectUrl($name, $object, array $parameters = array(), $absolute = false)
{
if ('show' == $name) {
return $this->getRouteGenerator()->generate('your_route_to_public_facing_view', [
'id' => $this->getUrlsafeIdentifier($object),
], $absolute );
}
$parameters['id'] = $this->getUrlsafeIdentifier($object);
return $this->generateUrl($name, $parameters, $absolute);
}
就是这样。没有使用模板。并且没有模板代码可以在所有其他管理员上运行。
要使链接自动出现,您必须在$showMapper
via中添加一些内容configureShowFields()
。(如果有人知道更好的方法,请告诉。)
覆盖generateObjectUrl()
还有另一个好处:如果您show
在 上显示一个按钮$listMapper
,那里的 URL 也会在那里更新。
编辑说:由于这会覆盖show
路线,您将无法再使用该内置功能。这对我来说没问题,因为我需要在加载所有前端 css 和 js 的情况下查看我的对象。