3

I'm creating a module using the toolbar api showing all administrative functions in a more compact toolbar. I'm having "cache" troubles showing the local tasks in the toolbar... How can I keep these items outside the toolbar cache?

In my custom module I use hook_toolbar to add the local tasks

/**
 * Implements hook_toolbar().
 */
function compact_toolbar_toolbar() {

    $items = [];
    ...

    $tasks = _compact_toolbar_local_tasks();
    $items = array_merge($items,$tasks);

    return $items;
}

And a function to generate the toolbar local tasks...

/**
 * Create local tasks toolbar items
 */
function _compact_toolbar_local_tasks() {

    $items = [];
    $route = \Drupal::routeMatch()->getRouteName();
    $manager = \Drupal::service('plugin.manager.menu.local_task');
    $primary = $manager->getLocalTasks($route, 0);

    foreach($primary['tabs'] as $key => $tab) {

        // add toolbar tab
        $items[$key] = [
            '#type' => 'toolbar_item',
            '#cache' => [ // Can I overrule the toolbar cache here?
                'max-age' => 0, 
            ],
            'tab' => [
                '#type' => 'link',
                '#title' => $tab['#link']['title'],
                '#url' => $tab['#link']['url'],
                '#access' => $tab['#access'],
                '#attributes' => [
                    'title' => $tab['#link']['title'],
                ],
            ],
            '#weight' => $tab['#weight'],
        ];

        // check if task is active
        if($tab['#active']) {
            $items[$key]['tab']['#attributes']['class'][] = 'is-active';
        }

        // get secondary tabs for each primary tab
        $route = $items[$key]['tab']['#url']->getRouteName();
        $secondary = $manager->getLocalTasks($route, 1);

        // get secondary tabs as tray
        if (!empty($secondary['tabs'])) {

            $links = [];
            $items[$key]['tab']['#attributes']['class'][] = 'toolbar-parent'; 

            // create renderable array of secondary links
            foreach ($secondary['tabs'] as $skey => $stab) {
                $sname = substr($skey, strrpos($key, '.') + 1);
                $links[$sname] = [
                    'type' => 'link',
                    'title' => $stab['#link']['title'],
                    'url' => $stab['#link']['url'],
                ];
            }

            // add tray with secondary tasks
            $items[$key]['tray'] = [
                '#heading' => t('Secondary tasks'),
                'toolbar_secondary_tasks' => [
                    '#theme' => 'links__toolbar',
                    '#links' => $links,
                    '#attributes' => ['class' => ['toolbar-menu']],
                ],
            ];

        }

    }

    return $items;
}

When I disable the cache in hook_page_top in core/modules/toolbar/toolbar.module everything works like a charm. Otherwise my custom items won't follow the current page...

/**
 * Implements hook_page_top().
 *
 * Add admin toolbar to the top of the page automatically.
 */
function toolbar_page_top(array &$page_top) {
  $page_top['toolbar'] = array(
    '#type' => 'toolbar',
    '#access' => \Drupal::currentUser()->hasPermission('access toolbar'),
    /*
    '#cache' => [
      'keys' => ['toolbar'],
      'contexts' => ['user.permissions'],
    ],
    */
  );
}

Can I overrule the toolbar cache by using the #cache array in my custom toolbar items? Which tags/context should I use?

This is how the toolbar looks like with my compact_toolbar module enabled... (but toolbar cache disabled) I really like the result! - I also made the menu behave like a simple dropdown menu and added a "content menu" to quickly add new content...

Compact toolbar example

  • I want this toolbar! It's beautiful, but I can't find any releases for compact_toolbar. Can you point me in the right direction? Thanks! – jimafisk Sep 29 '18 at 14:33
0

"The toolbar is a container for administrative and site-global interactive components."

https://api.drupal.org/api/drupal/core!modules!toolbar!toolbar.api.php/function/hook_toolbar/8.2.x

That would indicate that the toolbar is not the solution you are looking for as the more contextual tabs are not site global but page specific.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.