Dynamically Remove the delete Action Link

Another chapter, another problem to solve! I need to hide the delete button on the
list page if an entity is published. So... nope! We can't just go into config.yml
and add -delete. We need to override the list.html.twig template and take control
of those actions manually.

Copy that file. Then, up inside our views directory, I want to show the other
way of overriding templates: by convention. Create a new easy_admin directory,
and paste the template there and... that's it! EasyAdminBundle will automatically
know to use our list template.

Ok, refresh the genus list page! Awesome! This first dump is from list.html.twig.
It has the same fields configuration we've been looking at in the profiler, a
paginator object and a few other things, including configuration for this specific
section.

The other dumps come from _id.html.twig. The big difference is that we're rendering
oneGenus each time this template is called. So it has an item variable
set to the Genus object. That will be super handy. If some of the other keys
are tough to look at, remember, a lot of this already lives in the EasyAdminBundle
profiler area.

The template it renders - _actions.html.twig - generates a link at the end
of the row for each action.

Let's dump _list_item_actions to see exactly what it looks like.

Ah, ok! It's an array with 3 keys: edit, show and delete. We need to remove
that delete key, only if the entity is published. But how?

Here's my idea: if we override the item_actions block, we could remove the
delete key from the _list_item_actions array and then call the parent item_actions
block. It would use the new, smaller _list_item_actions.

Start by deleting everything and extending the base layout: @EasyAdmin/default/list.html.twig...
so that we don't need to duplicate everything:

Twig isn't really meant for complex logic like removing keys from an array. But,
to accomplish our goal, we don't have any other choice. So, set _list_item_actions
= _list_item_actions|filter_admin_actions(item):

Down below, create public function filterActions() with two arguments. First,
it will be passed an $itemActions array - that's the _list_item_actions variable.
And second, $item: whatever entity is being listed at that moment:

So... we don't need to configure anything: EasyAdminExtension will automatically be registered
as a service and tagged with twig.extension. In other words... it should just work.

Let's go. Refresh... and hold your breath.

Haha, it kind of worked! Delete is gone... but so is everything else. And you
may have noticed why. We did change the _list_item_actions variable... but we
forgot to call the parent block. Add {{ parent() }}:

Try it again. Got it! The delete icon is only there when the item is not published.
This was a tricky example... which is why we did it! But usually, customizing things
is easier. Technically, the user could still go directly to the URL to delete the
Genus, but we'll see how to close that down later.

Leave a comment!

Yeah template overriding is a tricky thing, to override bundle templates, you should place it in:templates/bundles/EasyAdminBundle/default/list.html.twigand your extends string will be like:{% extends '@!EasyAdmin/default/list.html.twig' %}Then it will work as expected.

So it should be at the top of your services.yml if you want to have service auto-registration. Let's add it to your services.yml. Do you still have the error about?

> A "tags" entry must be an array for service "AppBundle\Controller\" in ...

Please, try again and make sure you don't miss any brackets, etc. and your syntax is a valid YAML.

Btw, what version of Symfony do you use? Because this feature is new and does not work for Symfony version less than v3.3, see related discussion here: https://github.com/symfony/... . So the only way to use it is upgrade Symfony to 3.3 at least.

Cheers!

2018-01-17Bertin van den Ham

I've changed the indent to 4 spaces. Also my previous comment has the services.yml. But i will post it again.

But when is use the services.yml from the start directory the following error accours

A "tags" entry must be an array for service "AppBundle\Controller\" in /home/vagrant/documents/development/aqua_note/app/config/services.yml. Check your YAML syntax in /home/vagrant/documents/development/aqua_note/app/config/services.yml (which is being imported from "/home/vagrant/documents/development/aqua_note/app/config/config.yml").

So i miss something but couldn't find out what

2018-01-16Victor Bocharsky

Hey Bertin,

First of all, I see you have different indentation styles in one file, you use 4 spaces for it, but for the last service "app.form.help_form_extension" you use only 2 spaces. That could be a problem, first of all try to stick to a one style, I'd say it's easy to tweak the last service to use 4 spaces too for all:

Also, in the error message I see we're talking about "AppBundle\Controller\" service, but I don't see it in your output. Did you show the content of proper file? Could you show the content of "/home/vagrant/documents/development/aqua_note/app/config/services.yml"? Because the problem should be in it.

Cheers!

2018-01-14Bertin van den Ham

I’m getting the following error:Unknown "filter_admin_actions" filter in easy_admin/list.html.twig at line 4.I’ve created the file EasyAdminExtension.php, with the functions:- getFilters()- filterActions(array $itemActions, $item)

Also i’ve created the new folder easy_admin (app/resources/views/easy_admin) with the list.html.twigList.html.twig looks like:

When I change my services.yml I get a new error:A "tags" entry must be an array for service "AppBundle\Controller\" in /home/vagrant/documents/development/aqua_note/app/config/services.yml. Check your YAML syntax in /home/vagrant/documents/development/aqua_note/app/config/services.yml (which is being imported from "/home/vagrant/documents/development/aqua_note/app/config/config.yml").

How could I solve this issue?

2017-10-09axa

Hello Victor,Yes, it is clear now. Thanks.

2017-10-09Victor Bocharsky

Yo Axa!

Good question! :) You're totally right, filterActions() requires 2 args, but you need to know how Twig filters work. The 1st argument to the Twig filter *is always* a value which is on the left of the pipe "|" char. In your case, the first argument to filterActions() is the value of "_list_item_actions" variable, because it's standing right before | filter_admin_actions(). So the *second* argument to filterActions() is always the *first* argument in Twig filer parentheses, i.e. "item" variable in "|filter_admin_actions(item)". Does it clear for you now? Also, you can read official docs about Twig filter: https://twig.symfony.com/do...

Cheers!

2017-10-07axa

Hello guys,You set up in twig "_list_item_actions|filter_admin_actions(item)" with one argument 'item'.But in Twig extension we have public function filterActions(array $itemActions, $item) with two arguments. How twig knows about $itemActions?

This is a special feature of EasyAdminBundle. In the previous chapter, I quickly mention that in their docs, they talk about all the different options for overriding templates: https://symfony.com/doc/cur.... One of them is to create this easy_admin directory: the bundle is programmed to look there.

Cheers!

2017-08-14Billy Van

Hello guys! How to know name of directory (f.e. easy_admin) which EasyAdminBundle will automatically to use instead of default?