The "rolling patch" in #1137920: Fix toolbar on small screen sizes and redesign toolbar for desktop defines a new hook so that other modules can add their own menus to the toolbar. This hook should be documented in toolbar.api.php. If the Toolbar module implements its own hook, then it will serve as an example for other modules and also simplify the code in toolbar_view().

While working on this, I intend to do additional code review and clean-up. I am considering changing the name of the hook from hook_toolbar_register_tabs() to hook_toolbar(), following the pattern of hook_menu(). I am also considering adding hook_toolbar_alter(), unless this introduces a performance hit.

Development

I do not plan to post patches on this issue. Instead, development will take place in http://drupal.org/sandbox/jessebeach/1749042, the same sandbox as #1137920: Fix toolbar on small screen sizes and redesign toolbar for desktop. Any progress made here will be incorporated into the "rolling patches" posted there.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

benjifisher’s picture

First commit: f464d29.

I added toolbar_toolbar_register_tabs(), moving some code out of toolbar_view(). I also made some smaller changes:

  1. Add titles (for hovering over the link) to the Home, Menu, and User tabs.
  2. Sort the tabs using drupal_sort_weight(). (I assigned Home and Menu the weights -10 and -5, respectively.)
benjifisher’s picture

Second commit: a116440.

Changed the hook name from hook_toolbar_register_tabs() to hook_toolbar() and added hook_toolbar_alter(). If we decide this is a bad idea, we can cherry-pick this out.

benjifisher’s picture

Third commit: 1d156df.

Code clean-up in toolbar_view().

benjifisher’s picture

Commit 8d87a02.

In hook_toolbar(), change $tab to $items as in hook_menu().

benjifisher’s picture

Commit 4c30b08.

Add hook documentation in the new file toolbar.api.php.

I did my best, but I hope others will add to the documentation. In particular, we should document the caching mechanism (maybe here). I am not sure how it works, but I notice that some changes do not take effect until I clear caches.

benjifisher’s picture

Commit 264f8ac.

I edited the comments in toolbar_view().

What should toolbar_view() do if two (or more) modules use the same key (or category)?

Until now,

  1. If the two modules both define the 'tab' key, the second wins.
  2. If the two modules both define the 'tray' key, the second wins.

Note that rthe commit in Comment #1 changes the interpretation of "second."

This commit modifies the behavior:

  1. If the two modules both define the 'tab' key, the second still wins, but log a message with watchdog().
  2. If the two modules both define the 'tray' key, then merge the two render elements.

I do not claim that either of these is a good idea! We need some discussion here. What are the use cases?

In particular, the current code uses pre_render functions to define the trays for User and Shortcut. I think that these functions ignore any other entries in the render elements, so other modules cannot add to these menus without overriding the pre_render functions. Of course, we could rewrite those functions.

benjifisher’s picture

Commit ceefb98.

Improved defaults for the tab render elements.

This commit has two effects that I can think of:

  1. If a tab is defined without an 'href' key, then it is marked up as plain text, not a link. The default CSS gets the layout messed up.
  2. If the tab already sets $tab['attributes']['class'] = array('tab'), then the previous version would produce markup <a class="tab tab" ...> This commit avoids doubling the 'tab' class.
benjifisher’s picture

Commit: 7ba8a76.

Add paths to Toolbar tabs.

If javascript is disabled, then the Menu, Shortcut, and User tabs should link to something useful, not the home page. I make Menu a link to /admin, Shortcut link to /admin/config/user-interface/shortcut, and User link to /user.

benjifisher’s picture

Regarding the questions in #6, compare with hook_menu(). Because menu_router_build() uses array_merge(), the first module to define a given menu path in hook_menu() wins:

function menu_router_build() {
  // We need to manually call each module so that we can know which module
  // a given item came from.
  $callbacks = array();
  foreach (module_implements('menu') as $module) {
    $router_items = call_user_func($module . '_menu');
    if (isset($router_items) && is_array($router_items)) {
      foreach (array_keys($router_items) as $path) {
        $router_items[$path]['module'] = $module;
      }
      $callbacks = array_merge($callbacks, $router_items);
    }
  }
  // Alter the menu as defined in modules, keys are like user/%user.
  drupal_alter('menu', $callbacks);
  list($menu, $masks) = _menu_router_build($callbacks);
  _menu_router_cache($menu);

  return array($menu, $masks);
}
jessebeach’s picture

@benjifisher, great work so far! I've merged the changes in node/1830526-toolbar-hooks as of 7ba8a762c740408d7425efbb16653d59dc775151 into node/1137920-responsive-toolbar. You're code is leaps better than what I had and I think it'll help us in the effort to get it rtbc'ed. You'll want to rebase your branch on 1137920 with a fast-forward for further changes.

This commit modifies the behavior:

If the two modules both define the 'tab' key, the second still wins, but log a message with watchdog().
If the two modules both define the 'tray' key, then merge the two render elements.
I do not claim that either of these is a good idea! We need some discussion here. What are the use cases?

The only use-case I can think of is the Edit module or maybe something like Commerce that registers a top-level tab. I can't foresee yet why contrib will want to augment the Shortcut or User tray. In any case, merging the contents seems like the wrong strategy. I think we just want wholesale replacement of the content if a module defines an existing tray name. Hopefully modules will just use their own name which is avoid namespace clashing. I'm willing to let it be as it is and see what folks say in review.

benjifisher’s picture

@jessebeach:

I am inclined to take the same approach as hook_menu() (see my comment #9 above). In other words, do not allow modifications in hook_toolbar(). If another module wants to modify the User menu, it should implement hook_toolbar_alter(). But I am open to other suggestions.

How about these for use cases?

  1. The Profile2 module wants to add a link (or links) to edit your profile(s).
  2. Views Bulk Operations wants to add a link to admin/user/user2 (I think), its alternative user-management page.
  3. The OpenPublish distrubution wants to provide a default set of shortcut links. (Maybe this can already be done using the Shortcut module?)
jessebeach’s picture

Status: Active » Needs work

@benjifisher. I'm mostly happy with what you put together in the branch and what's therefore been merged into #1137920. Did you want to do any refactoring before we put the code up for review through #1137920?

benjifisher’s picture

@jessebeach:

I do not plan to do any more work on this branch without answers to some of the questions I posed in the comments. It seems unlikely that anyone else will offer opinions on them until the changes are reviewed as part of #1137920.

Short answer: no.

jessebeach’s picture

Status: Needs work » Closed (duplicate)
benjifisher’s picture

Status: Closed (duplicate) » Needs review
FileSize
565 bytes

I found a typo (my fault). Please either apply this patch or cherry-pick 09820e3 from the sandbox.

jessebeach’s picture

Updated the spelling correction noted in #15 in the #1137920 issue.

benjifisher’s picture

Status: Needs review » Fixed

I checked the interdiff posted with #1137920-280: Fix toolbar on small screen sizes and redesign toolbar for desktop. The correction is there, so changing the status to Fixed.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.