How to create custom local tasks programmatically in drupal 8 & 9
Local tasks are generally placed directly above content on pages(up to two levels), but can be dynamically positioned as a block. These are mostly used on administrative pages but frontend pages like user pages or the registration/login/new password pages also use local tasks.
Most local tasks that you need to define will be static, and can therefore be provided in a file named after your module, e.g., if the module name is 'example', the file will be example.links.task.yml
and placed in the root of the module.
Example 1:
example.admin: route_name: example.admin title: 'Settings' base_route: example.admin example.admin_3rd_party: route_name: example.admin_3rd_party title: 'Third party services' base_route: example.admin weight: 100
Example 2 - local tasks defined by the block_content module:
entity.block_content.collection:
title: 'Custom block library'
route_name: entity.block_content.collection
base_route: block.admin_display
block_content.list_sub:
title: Blocks
route_name: entity.block_content.collection
parent_id: entity.block_content.collection
entity.block_content_type.collection:
title: Types
route_name: entity.block_content_type.collection
parent_id: entity.block_content.collection
weight: 1
entity.block_content_type.edit_form:
title: 'Edit'
route_name: entity.block_content_type.edit_form
base_route: entity.block_content_type.edit_form
entity.block_content.delete_form:
title: Delete
route_name: entity.block_content.delete_form
base_route: entity.block_content.canonical
Visually, the first three appear integrated in the block admin interface:
Example how to create dynamic local tasks
Sometimes a static list of local tasks is not enough. For example, Views, Content translation and Configuration translation add local tasks to a wide variety of pages in Drupal. To achieve this, add a local task with a derivative key pointing to a class that generates the dynamic local tasks. Your example.links.task.yml
would look like the following:
example.local_tasks:
deriver: 'Drupal\example\Plugin\Derivative\DynamicLocalTasks'
weight: 100
Generate the local tasks in the derivative class placed at src/Plugin/Derivative/DynamicLocalTasks.php
based on the above reference:
namespace Drupal\example\Plugin\Derivative;
use Drupal\Component\Plugin\Derivative\DeriverBase;
/**
* Defines dynamic local tasks.
*/
class DynamicLocalTasks extends DeriverBase {
/**
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition) {
// Implement dynamic logic to provide values for the same keys as in example.links.task.yml.
$this->derivatives['example.task_id'] = $base_plugin_definition;
$this->derivatives['example.task_id']['title'] = "I'm a tab";
$this->derivatives['example.task_id']['route_name'] = 'example.route';
return parent::getDerivativeDefinitions($base_plugin_definition);
}
}
In this example, we don't do anything dynamic, but you would only use this code structure if you do need to generate dynamic local tasks.
Example how to customize local task behavior
You can customize the behavior of your local tasks by extending LocalTaskDefault. For example, you can provide a dynamic title. You need to provide the class name of the custom local task implementation on the local task definition in the class
key.
For example, see UserTrackerTab which is dependent on the current user ID in the path. It is defined with this tracker.links.task.yml
entry (note the class key):
tracker.users_recent_tab:
route_name: tracker.users_recent_content
title: 'My recent content'
base_route: tracker.page
class: '\Drupal\tracker\Plugin\Menu\UserTrackerTab'