我们将SonataAdminBundle与我们的Symfony2应用程序一起使用。编辑实体时,我想将自己的操作添加到位于右上角的下拉菜单中,但我不知道这是如何工作的。
我知道我可以通过configureRoutes(RouteCollection $collection)
添加自己的路由,以及如何在列表视图中的实体后面添加批处理操作或添加自己的操作,但是如何在编辑视图的操作下拉列表中添加自己的链接?
它基本上只是一个链接,例如"在前端显示此实体",因此不需要大的逻辑。
一种方法是覆盖编辑时使用的模板。现在,您需要做的是:
-
在名为
SonataAdminBundle
的app/Resources
中创建新目录(如果还没有)。在里面,创建另一个叫做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')
将返回编辑操作的路由。如果您希望链接显示在所有编辑操作中,则可以将其删除。使用admin.id(object)
更改路线名称<a href="/generate/path/with/your/route">View in Frontend</a>
,您应该很高兴。
在 admin 类中,重写以下方法:
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>
另一种方法是覆盖对象 admin 类中generateObjectUrl()
的方法。
/**
* @see SonataAdminBundleAdminAdmin::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
添加内容 configureShowFields()
.(如果有人知道更好的方法,请告诉。
覆盖generateObjectUrl()
还有另一个好处:如果您在$listMapper
上显示show
按钮,那里的 URL 也会在那里更新。
编辑为:由于这会覆盖show
路由,因此您将无法再使用该内置功能。这对我来说没关系,因为我需要在加载所有前端 css 和 js 的情况下查看我的对象。