---
url: 'https://metadrop.net/en/articles/local-tasks-hierarchy-drupal-10'
title: 'Local tasks hierarchy on Drupal 10'
author: 'Eduardo Morales'
date: '2024-11-13T13:14:50+00:00'
updated: '2024-11-14T15:41:36+00:00'
type: article
summary: 'Implement and understand how to develop two-level local tasks in Drupal 10. Learn to create a hierarchical structure of local tasks using YAML files and discover how the Drupal community can offer effective solutions.'
tags:
  - 'Drupal Planet'
image: 'https://metadrop.net/sites/default/files/styles/full/public/2024-11/local_tasks.jpg.webp?itok=S1ZCQdoO'
published: true
og:
  determiner: Automatic
  site_name: Metadrop
  'image:url': 'https://metadrop.net/sites/default/files/styles/full/public/2024-11/local_tasks.jpg.webp?itok=S1ZCQdoO'
  'image:type': image/jpeg
  'image:width': '600'
  'image:height': '270'
  'image:alt': 'Local tasks hierarchy on Drupal 10'
  street_address: 'Calle Manuel Luna, 12, 3 Dcha'
  locality: Madrid
  region: Madrid
  postal_code: '28020'
  country_name: España
  email: hola@metadrop.net
  phone_number: '910053180'
schema:
  '@context': 'https://schema.org'
  '@graph':
    -
      '@type': Article
      '@id': 'https://metadrop.net/en/articles/local-tasks-hierarchy-drupal-10#article'
      name: 'Local tasks hierarchy on Drupal 10'
      headline: 'Local tasks hierarchy on Drupal 10'
      description: 'Implement and understand how to develop two-level local tasks in Drupal 10. Learn to create a hierarchical structure of local tasks using YAML files and discover how the Drupal community can offer effective solutions.'
      image:
        '@type': ImageObject
        url: 'https://metadrop.net/sites/default/files/styles/full/public/2024-11/local_tasks.jpg.webp?itok=S1ZCQdoO'
        width: '600'
        height: '270'
      datePublished: '2024-11-15T14:14:50+0100'
      dateModified: '2024-11-14T16:41:36+0100'
      author:
        '@type': Person
        name: 'Eduardo Morales'
      publisher:
        '@type': Organization
        '@id': 'https://metadrop.net/#organization'
      mainEntityOfPage: 'https://metadrop.net/en/articles/local-tasks-hierarchy-drupal-10'
    -
      '@type': Organization
      '@id': 'https://metadrop.net/#organization'
      url: 'https://metadrop.net/'
      name: Metadrop
      sameAs:
        - 'https://www.drupal.org/metadrop'
        - 'https://twitter.com/metadrop'
        - 'https://asociaciondrupal.es/partner/metadrop'
        - 'https://www.linkedin.com/company/metadrop'
      logo:
        '@type': ImageObject
        url: 'https://metadrop.net/themes/custom/mdrop_radix/logo-metadrop-500-500.jpg'
        width: '500'
        height: '500'
    -
      '@type': ItemPage
      '@id': 'https://metadrop.net/en/articles/local-tasks-hierarchy-drupal-10'
      breadcrumb:
        '@type': BreadcrumbList
        itemListElement:
          -
            '@type': ListItem
            position: 1
            name: Home
            item: 'https://metadrop.net/en'
          -
            '@type': ListItem
            position: 2
            name: 'Expert Drupal & Tech Articles'
            item: 'https://metadrop.net/en/articles'
      publisher:
        '@type': Organization
        '@id': 'https://metadrop.net/#organization'
---
 1. [Articles](https://metadrop.net/en/articles)
 
  

# Local tasks hierarchy on Drupal 10

Friday, November 15, 2024

 

 



Implement and understand how to develop two-level local tasks in Drupal 10. Learn to create a hierarchical structure of local tasks using YAML files and discover how the Drupal community can offer effective solutions.



   



Recently, in one of our projects with **Drupal 10**, we faced an interesting challenge: implementing two-level "**local tasks**" for a specific functionality of our module. Despite the **number of documentation** related to local tasks in Drupal, setting up two levels of these tasks proved challenging, as we couldn't get them to display in the way we needed. However, after exhaustive research, we found an **example in an existing module** that helped us solve the problem.

 

 

## Exploring the Problem

The need was to add a main "**local task**" and three associated **subtasks** that would show up when viewing or editing a node. Initially, the main obstacle was finding the right way to implement **two levels of local tasks**.

## The Solution: Inspiration from Contributed Modules

During our search among existing **contributed modules,** we found inspiration. Drupal.org has **very good documentation**, and even module issues can often provide clues on how to solve certain problems or needs. Fortunately, the **Drupal community** is extensive, and there is a high probability that someone has faced the problem before.

The **documentation on multi-level "local tasks"** already exists on [Drupal.org,](https://www.drupal.org/ "Drupal org") you can view it at ["Providing module-defined local tasks"](https://www.drupal.org/docs/drupal-apis/menu-api/providing-module-defined-local-tasks), but we had trouble understanding how to implement it properly.

We also looked for **examples** in the [Examples](https://www.drupal.org/project/examples "Examples") module that could help us.

In this scenario, it was the `webform_node` module that inspired us. This module manages multiple levels of local tasks as it provides a **webform** content type that defines certain tasks to view the number of submissions made to the webform and allows you to manage them, and this was the **starting point of our solution**. Once the module was installed and running we could investigate and understand what and how we needed to implement it.

## The Solution: Implementation

Instead of providing a detailed explanation of each aspect, as there is very good documentation on **routes** and "**local tasks**", we will explain the part that was "problematic" for us.

We defined our **routes** in the `mymodule.routing.yml` file as follows:

```yaml
# Definition of the main route.
mymodule.node.main:
  # Sets the URL that triggers this route, with a placeholder for a specific node.
  path: '/node/{node}/mymodule/main'
  defaults:
    # Specifies the page title for this route.
    _title: 'Main route'
    # Indicates the form that should be used when accessing this route.
    _form: 'Drupal\mymodule\Form\MyModuleForm'
  # Conditions that must be met to access this route.
  requirements:
    # The route requires the user to have this specific permission.
    _permission: 'administer site configuration'
    # Uses a controller method to check custom access.
    _custom_access: '\Drupal\mymodule\Controller\MymoduleNodeController::access'
    # Ensures that the {node} placeholder is an integer.
    node: \d+
  options:
    # Indicates that this is an admin route, which affects its display in certain backend areas.
    _admin_route: TRUE
    parameters:
      node:
        # Establishes that the {node} parameter must represent an entity of type node.
        type: entity:node
```

We also defined the remaining routes, verifying that each included the **necessary controllers** to handle their specific functions. So far, nothing new.

## The Key: Two Levels in Local Task

The real challenge was configuring the local tasks with **hierarchy** using the `mymodule.links.task.yml` file. Here we discovered that the key to enabling a second level lies in the correct implementation of the `parent_id` attribute.

In the following example, a **main task** is defined that points to the "`mymodule.node.main`" route named "`mymodule.task_main`", and its **base route** is `entity.node.canonical` since we wanted it to be displayed alongside the rest of the node's tasks. You can see that the "`mymodule.node.main`" route appears in the definition of two tasks, as it is both a child and the main task and that both the "`mymodule.node.main`" route and the others have the main task "`mymodule.task_main`" as their parent.

```yaml
# Define the main task
mymodule.task_main:
  # The title of the task that will be visible in the user interface.
  title: 'Main task'
  # Specifies the name of the route to which the task is associated.
  route_name: mymodule.node.main
  # Determines the base route where this task will appear in the task set.
  base_route: entity.node.canonical
  # Controls the order in which the tasks appear; a smaller value appears further to the left.
  weight: 10
# Define a subtask under the main task already defined.
mymodule.subtask_main:
  # Visible title for the subtask.
  title: 'Main subtask'
  # Name of the route that the subtask uses, can be the same as the main task.
  route_name: mymodule.node.main
  # Specifies that this task is a child of the ID of the main task, thus defining the second level of hierarchy.
  parent_id: mymodule.task_main
 
mymodule.subtask_secondary:
  title: 'Subtask secondary'
  route_name: mymodule.node.secondary
  parent_id: mymodule.task_main
 
mymodule.subtask_other:
  title: 'Other subtask'
  route_name: mymodule.node.subtask_other
  parent_id: mymodule.task_main

```

By defining the `parent_id`, we established the necessary **hierarchical relationship** for each **subtask** so that Drupal could understand and display these tasks correctly under the main task "mymodule.task\_main".

## Conclusion

The ability of Drupal to be **extensible and highly customizable** is one of its great strengths, and thanks to its **community** and **open source**, it is possible to find examples and solutions for almost any challenge. Through the review of contributed modules and a basic understanding of how to integrate `parent_id` in the `links.task.yml`, we successfully implemented our two-level "**local tasks**" system.

In addition to resolving the current challenge, this exercise significantly enhanced our knowledge of **Drupal's possibilities** and the importance of an active and collaborative community. When faced with a similar problem, consider that solutions may often be conveniently located in a click away within an **existing module**.

## Documentation

- [Examples Module](https://www.drupal.org/project/examples "Examples Module")
- [webform\_node module source code](https://git.drupalcode.org/project/webform/-/tree/6.3.x/modules/webform_node?ref_type=heads "Webform node")
- [Local task documentation](https://www.drupal.org/docs/drupal-apis/menu-api/providing-module-defined-local-tasks "Local task documentation")



- Eduardo Morales
    
    Senior Drupal developer
 
[Module development and third-party integrations with Drupal](https://metadrop.net/en/services/drupal/integrations " See Module development and third-party integrations with Drupal")

Metadrop connects Drupal to your CRM, ERP, payment, and marketing stack — Salesforce, Microsoft Dynamics, BBVA virtual POS, Workday, and Keepeek — with custom modules and secure, GDPR-compliant APIs.

 

 See more