Do you want to know how to Drupal?

Let's Drupal

How to add a local task to custom page in Drupal?

In the previous post How to add a local task (tab) in Drupal?, we have reviewed how to add a static tab to the page with tabs, but what if we want to add a tab to our custom page?

Lets imagine we have a parent page and two child pages

E-shop Settings

  • Products settings
  • Categories settings

You can find the final result here: https://github.com/LOBsTerr/drupal-modules-examples/tree/master/local_tasks

First we will add custom pages and routes for them, for this we need to add to your controller (in my case LocalTasksController.php)

public function eshopSettings() {
    return [
      '#markup' => $this->t('This is a parent settings page. This page has two child pages: <a href="@products_settings_url">Products settings</a> and <a href="@categories_settings_url">Categories settings</a>', [
        '@products_settings_url' => Url::fromRoute('local_tasks.products_settings')->toString(),
        '@categories_settings_url' => Url::fromRoute('local_tasks.categories_settings')->toString(),
      ]),
    ];
  }

  public function eshopMetaSettings() {
    return [
      '#markup' => $this->t('This is a meta settings page'),
    ];
  }

  public function productsSettings() {
    return [
      '#markup' => $this->t('This is a products settings page'),
    ];
  }

  public function categoriesSettings() {
    return [
      '#markup' => $this->t('This is a categories settings page'),
    ];
  }

Then we will provide routes for them

# Routes for custom page (eshop) tabs.
local_tasks.eshop_settings:
  path: '/eshop-settings'
  defaults:
    _controller: '\Drupal\local_tasks\Controller\LocalTasksController::eshopSettings'
    _title: 'E-shop settings'
  requirements:
    _permission: 'access content'

local_tasks.eshop_meta_settings:
  path: '/eshop-meta-settings'
  defaults:
    _controller: '\Drupal\local_tasks\Controller\LocalTasksController::eshopMetaSettings'
    _title: 'E-shop meta settings'
  requirements:
    _permission: 'access content'

local_tasks.products_settings:
  path: '/eshop-settings/products-settings'
  defaults:
    _controller: '\Drupal\local_tasks\Controller\LocalTasksController::productsSettings'
    _title: 'Products settings'
  requirements:
    _permission: 'access content'

local_tasks.categories_settings:
  path: '/eshop-settings/categories-settings'
  defaults:
    _controller: '\Drupal\local_tasks\Controller\LocalTasksController::categoriesSettings'
    _title: 'Categories settings'
  requirements:
    _permission: 'access content'

Once it is done, you can check these pages.

/eshop-settings

/eshop-meta-settings

/eshop-settings/products-settings

/eshop-settings/categories-settings

The next step to add tabs. First we define the default tab. For the default tab the base_route should be equal route_name 

# in this example we add tabs for custom page.
local_tasks.eshop_settings: # The ID of local task is the same as route, to make it easier to control.
  route_name: 'local_tasks.eshop_settings' # A route for e-shop settings, provided in local_tasks.routing.yml.
  title: 'Eshop settings' # This string will be displayed as a title of a tab.
  base_route: 'local_tasks.eshop_settings' # !!!important For default tab the base_route should be the same as route_name.
  weight: 10

local_tasks.eshop_meta_settings: # The ID of local task is the same as route, to make it easier to control.
  route_name: 'local_tasks.eshop_meta_settings' # A route for e-shop settings, provided in local_tasks.routing.yml.
  title: 'Eshop meta settings' # This string will be displayed as a title of a tab.
  base_route: 'local_tasks.eshop_settings' # This will allow to display it in the same level with "E-shop settings"
  weight: 20

local_tasks.products_settings: # The ID of local task is the same as route, to make it easier to control.
  route_name: 'local_tasks.products_settings' # A route for e-shop settings, provided in local_tasks.routing.yml.
  title: 'Products settings' # This string will be displayed as a title of a tab.
  base_route: 'local_tasks.eshop_settings' # Because we want to group tabs we should set to default one, in our case E-shop settings.
  parent_id: 'local_tasks.eshop_settings' # This will display item under "Eshop settings" tab.
  weight: 10

local_tasks.categories_settings: # The ID of local task is the same as route, to make it easier to control.
  route_name: 'local_tasks.categories_settings' # A route for e-shop settings, provided in local_tasks.routing.yml.
  title: 'Categories settings' # This string will be displayed as a title of a tab.
  base_route: 'local_tasks.eshop_settings' # Because we want to group tabs we should set to default one, in our case E-shop settings.
  parent_id: 'local_tasks.eshop_settings' # This will display item under "Eshop settings" tab.
  weight: 20

Clean the cache and open /eshop-settings, you will see your tabs. At that moment all tabs are in the same level, but we want them displayed as a sublevel. For these we need to define parent_id and set it to local_tasks.eshop_settings in order to display them as under "E-shop settings".

Keep in mind that there should be at least two tabs in the level. In other case the tabs will be hidden.