将自己的操作添加到 SonataAdminBundle 下拉菜单

Posted

技术标签:

【中文标题】将自己的操作添加到 SonataAdminBundle 下拉菜单【英文标题】:Adding own action to SonataAdminBundle dropdown menu 【发布时间】:2015-09-03 17:24:53 【问题描述】:

我们将 SonataAdminBundle 与 Symfony2 应用程序一起使用。编辑实体时,我想将自己的操作添加到位于右上角的下拉菜单中,但我不知道这是如何工作的。

我知道我可以通过configureRoutes(RouteCollection $collection) 添加自己的路由以及如何在列表视图中添加批处理操作或在实体后面添加自己的操作,但是如何在编辑视图的操作下拉列表中添加自己的链接?

它基本上只是一个“在前端显示这个实体”之类的链接,所以不需要大逻辑。

【问题讨论】:

【参考方案1】:

一种方法是覆盖编辑时使用的模板。现在,您需要做的是:

app/Resources 中创建名为SonataAdminBundle 的新目录(如果您还没有)。在里面,创建另一个名为views 的文件。这将创建一个类似app/Resources/SonataAdminBundle/views 的路径。这是 Symfony 的基本模板覆盖。您可以阅读有关该主题的更多信息here.

现在,您应该按照与原始包相同的路径复制原始模板。我们这里感兴趣的模板文件位于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 %

现在剩下要做的就是在最后一个 &lt;li&gt; 标记之后插入您的链接。

% 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)&lt;a href="/generate/path/with/your/route"&gt;View in Frontend&lt;/a&gt; 更改为您的路线名称,您应该一切顺利。

【讨论】:

感谢您的解释。我在使用那些奇怪的模板缓存时遇到了一些问题,但现在它可以工作了! 啊……对。无论当前环境如何,我都完全忘记了自己添加以删除缓存。无论如何,很高兴我能提供帮助。【参考方案2】:

另一种方法是覆盖对象管理类中的方法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);

就是这样。没有使用模板。并且没有模板代码可以在所有其他管理员上运行。

要让链接自动显示,您必须通过configureShowFields()$showMapper 添加一些内容。 (如果有人知道更好的方法,请告诉。)

覆盖generateObjectUrl() 有另一个好处:如果您在$listMapper 上显示show 按钮,那里的URL 也会在那里更新。

编辑说:由于这覆盖了show 路由,您将无法再使用该内置功能。这对我来说没问题,因为我需要查看加载了所有前端 css 和 js 的对象。

【讨论】:

【参考方案3】:

在您的管理类中,覆盖以下方法:

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>

【讨论】:

以上是关于将自己的操作添加到 SonataAdminBundle 下拉菜单的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 Swift 中捕获的图像中添加自己的元数据

将Hexo搭建到自己的服务器上

如何将OpenSSL添加到Xcode项目中

PDF文件压缩方法,什么方法压缩PDF简单

Vim的常用操作

github常见操作