Skip to content

Dynamic HTML Attributes via Callables in Actions #7527

@ucscode

Description

@ucscode

1. The Problem: "Static Metadata in a Dynamic Grid"

EasyAdmin’s Action configuration is currently "eager." When you define attributes, they are applied to every row in the Index or Detail view identically.

  • The Limitation: You cannot currently set an attribute based on the entity's state (e.g., data-status="active" vs data-status="locked").
  • The Workaround: Developers must currently override the crud/action.html.twig template globally or use a DisplayCallable on a field to "fake" a button, which breaks the Action/Batch system.

2. The Solution: Callable Support for setHtmlAttributes

The setHtmlAttributes() should accept a callable that receives the entity instance. This allows for "Lazy" attribute resolution during the rendering loop.

Proposed Signature:

// Existing:
public function setHtmlAttributes(array $attributes): self

// Proposed:
public function setHtmlAttributes(array|callable $attributes): self

3. Usage Example

In a CrudController, you could now define logic that reacts to the specific row data:

public function configureActions(Actions $actions): Actions
{
    $editAction = Action::new('edit')
        ->setHtmlAttributes(function ($entity) {
            return [
                'data-entity-id' => $entity->getId(),
                'class' => $entity->isArchived() ? 'btn-secondary disabled' : 'btn-primary',
                'title' => sprintf('Modify %s', $entity->getName()),
            ];
        });

    return $actions->add(Crud::PAGE_INDEX, $editAction);
}

4. The Logic: Late-Binding in ActionFactory

The core of this feature request is moving the attribute resolution from Configuration Time to Rendering Time.


This removes the need for "Logic-Heavy" Twig templates. By allowing the Controller to define the HTML state, we keep the View layer clean. It also aligns perfectly with how setLabel() and other methods in EasyAdmin are starting to evolve toward closure-based configuration.

Feature Current State Proposed Behavior
Attribute Logic Hardcoded/Static for all rows. Resolved per-entity (Dynamic).
CSS Interaction Requires custom CSS/JS selectors. Direct attribute injection (e.g., for Tailwind or Bootstrap).
Developer Experience High friction (Template overrides). Low friction (Standard PHP closure).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions