Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding own action to SonataAdminBundle dropdown menu

Tags:

symfony

sonata

We use the SonataAdminBundle with our Symfony2 application. When editing an entity I want to add an own action to the dropdown menu which is located in the top right corner, but I have no idea how this works.

I know I can add own routes via configureRoutes(RouteCollection $collection) and how to add batch actions or add own actions behind entities in the list view, but how can I add an own link in the actions dropdown in the edit view?

It is basically just a link like "Show me this entity in the frontend", so no big logic is needed.

like image 871
Malte Avatar asked Jan 09 '23 03:01

Malte


2 Answers

One way would be to override the template that is used when editing. Now, what you need to do is:

  • Create new directory (if you already haven't) in app/Resources called SonataAdminBundle. Inside, create another one called views. This would create a path like app/Resources/SonataAdminBundle/views. This is Symfony basic template overriding. You can read more on that subject here.

  • Now, you should copy the original template following the same path as it is, inside the original bundle. The template file we are interested here is located in sonata-project/admin-bundle/Resources/views/CRUD/base_edit.html.twig. This means that you have to create another folder inside views (the one we just created in app, called CRUD. So, now we have to following path app/Resources/SonataAdminBundle/views/CRUD. Paste the template (base_edit.html.twig) inside and we can start editing.

Keep in mind that the following template is used in every edit action you have. So it's up to you whether you want to display that link in every edit_action or not. I will show you 1 way to limit that for specific action.

The block you gonna edit is {% block actions %} which is responsible for rendering the dropdown. This is how it should look now:

{% 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 %}

Now all that's left to do is insert your link after last <li> tag.

{% 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) will return the current ID of the item you edit. app.request.get('_route') will return the route of your edit action. You can remove that if you want your link to be displayed in all edit actions. Change <a href="/generate/path/with/your/route">View in Frontend</a> with your route name using admin.id(object) and you should be good to go.

like image 94
Artamiel Avatar answered Jan 10 '23 16:01

Artamiel


In your admin class, override the following method:

public function getActionButtons($action, $object = null)
{
    $list = parent::getActionButtons($action, $object);

    $list['upload'] = [
        'template' => ':admin:my_upload_button.html.twig',
    ];

    return $list;
}

This will add a custom action button on all the pages of this admin. You can add any logic in here to decide which pages ($action-s) you want to display the button on.

You can do what you want in the template, but just to complete my example and show the connection with my custom action:

<li>
    <a class="sonata-action-element" href="{{ admin.generateUrl('upload') }}">
        <i class="fa fa-cloud-upload" aria-hidden="true"></i>
        Upload stuff
    </a>
</li>
like image 45
lopsided Avatar answered Jan 10 '23 17:01

lopsided