How to make a Drupal 8 local task title dynamic

When defining local tasks (= tabs) in your Drupal 8 modules, you can specify a title for the tab via the 'title' property in your [MODULENAME].links.task.yml file.

However, in some cases you might want to make the task title dynamic, e.g. depending on the context of the entity where the tab is displayed.
This can be achieved by overriding the \Drupal\Core\Menu\LocalTaskDefault class with your own class for that tab.

Here is an example that uses a callback function to dynamically set the title, both for the route and the local task:

 

  1. Add the dynamic logic to your controller

    File: my_module/src/Controller/DynamicTabController.php
    <?php
    
    namespace Drupal\my_module\Controller;
    
    use Drupal\Core\Controller\ControllerBase;
    use Drupal\node\NodeInterface;
    
    /**
     * Controller for our dynamic tab.
     */
    class DynamicTabController extends ControllerBase {
    
      /**
       * Route title callback.
       *
       * @param \Drupal\node\NodeInterface $node
       *   The node entity.
       *
       * @return string
       *   The title.
       */
      public function getDynamicTabTitle(NodeInterface $node) {
        return $this->t('Dynamic tab for @type', ['@type' => $node->bundle()]);
      }
    
    }
    
  2. Use the dynamic title callback for your route

    File: my_module/my_module.routing.yml
    entity.node.dynamic_tab:
      path: '/node/{node}/dynamic_tab'
      defaults:
        _entity_form: 'node.dynamic_tab'
        _title_callback: '\Drupal\my_module\Controller\DynamicTabController::getDynamicTabTitle'
      requirements:
        _entity_access: 'node.view'
  3. Add your custom LocalTask plugin

    File: my_module/src/Plugin/Menu/LocalTask/DynamicTabLocalTask.php
    <?php
    
    namespace Drupal\my_module\Plugin\Menu\LocalTask;
    
    use Drupal\Core\Menu\LocalTaskDefault;
    use Drupal\Core\StringTranslation\StringTranslationTrait;
    use Drupal\node\NodeInterface;
    use Drupal\my_module\Controller\DynamicTabController;
    use Symfony\Component\HttpFoundation\Request;
    
    /**
     * Local task plugin to render dynamic tab title dynamically.
     */
    class DynamicTabLocalTask extends LocalTaskDefault {
    
      use StringTranslationTrait;
    
      /**
       * {@inheritdoc}
       */
      public function getTitle(Request $request = NULL) {
        $node = $request->attributes->get('node');
        if ($node instanceof NodeInterface) {
          $controller = new DynamicTabController();
          return $controller->getDynamicTabTitle($node);
        }
        return $this->t('Default');
      }
    
    }
    
  4. Set your custom class for your local task

    File: my_module/my_module.links.task.yml
    entity.node.dynamic_tab:
      route_name: entity.node.dynamic_tab
      base_route: entity.company.canonical
      title: 'Default'
      class: '\Drupal\my_module\Plugin\Menu\LocalTask\DynamicTabLocalTask'

Now the dynamic title will be used to render your tab name, and the tab page title.