Routes for local tasks do not have different requirements, compared to routes that are not used for local tasks, apart from being added in the .links.task.yml file for the module.
For example, the Book module define the following local task.
entity.node.book_outline_form:
route_name: entity.node.book_outline_form
base_route: entity.node.canonical
title: Outline
weight: 2
The route is defined by these lines.
entity.node.book_outline_form:
path: '/node/{node}/outline'
defaults:
_entity_form: 'node.book_outline'
_title: 'Outline'
requirements:
_permission: 'administer book outlines'
_entity_access: 'node.view'
node: \d+
options:
_node_operation_route: TRUE
In this case, the form is defined with _entity_form
. It could have used _form
too; in that case, the _form
value is the name (namespace included) of a class that implements FormInterface
, which is implemented by the FormBase
, a base class module can extend for their forms.
Other base classes that can be used for forms are ConfigFormBase
, for configuration forms, ConfirmFormBase
, for confirmation forms, or ImageEffectFormBase
, for an image effect settings.
Any route parameters are passed to the buildForm()
method any class that implements FormInterface
needs to implement.
The alternative is doing like the Book module does, adding a new form class using hook_entity_build()
and using _entity_form
in the route definition.
function book_entity_type_build(array &$entity_types) {
/** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */
$entity_types['node']->setFormClass('book_outline', 'Drupal\\book\\Form\\BookOutlineForm')
->setLinkTemplate('book-outline-form', '/node/{node}/outline')
->setLinkTemplate('book-remove-form', '/node/{node}/outline/remove')
->addConstraint('BookOutline', []);
}
In this case, the edited entity is passed in $this->entity
to the methods of the entity form class.