Hacking contextual links in Drupal 7

This blog post is more than 3 years old, so the content may be out of date.

Drupal 7 comes with some cool new tools like contextual links

Contextual links are added to blocks using hook_block_view or hook_block_view_alter:

$block = array(
  'subject' => t('Blog Archive'),
  'content' => array(
    'show_all_link' => l(t('All blog posts'), 'blog'),
    'archive' => $archive,
    '#theme' => 'wordpress_blog_archive',
    '#cache' => DRUPAL_CACHE_PER_PAGE,
    '#contextual_links' => array(
      'wordpress_blog' => array('node/add', array()),
    ),
  ),
);

The #contextual_links property is an array where each key is the name of the module which is implementing the contextual links:

    '#contextual_links' => array(
      'wordpress_blog' => ... // Links from the wordpress_blog module
      'node' => ...           // Links from the node module
      'menu' => ...           // Links from the menu module
    ),

Each module provides an array of 2 values which combine to form a path. For example:

  • node/23
    '#contextual_links' => array(
      'xxx' => array('node', array(23)),
    )
  • admin/content
    '#contextual_links' => array(
      'xxx' => array('admin/content', array()),
    )
  • Paths which are implemented in hook_menu using %param - e.g. node/%node - should pass 'node' as the first array value, and the specific node id in the second.

The context-links are found by searching the menu system for those links which are child links of the path supplied, and are configured to be context items.

As an example /node/%node has the following children:

  • node/%node/view (default local task) with no 'context' defined
  • node/%node/edit with context: MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE
  • node/%node/revisions with context: MENU_CONTEXT_PAGE
  • node/%node/report-as-spam with context: MENU_CONTEXT_INLINE

If node/23 is provided, the links for 'edit' and 'report-as-spam' will be returned.

Adding links which aren't child menu items

The Wordpress Blog module is a prime example: it provides a 'Blog Archive' block, and adding a contextual link to 'Create Wordpress Blog Post' is a great usability enhancement.

The problem is that node/add/wordpress_blog is a normal menu item - it's not a child task of anything. So we need to hack the menu to make this available to contextual links:

function wordpress_blog_menu_alter(&$menu) {
  $menu['node/add/wordpress-blog']['_tab'] = TRUE;
  $menu['node/add/wordpress-blog']['tab_parent'] = 'node/add';
  $menu['node/add/wordpress-blog']['context'] = MENU_CONTEXT_INLINE;
}

Now when you pass the context of node/add in the contextual-links, node/add/wordpress-blog is found as an in-context child of node/add.

Caution! This may break the menu system :-)
I haven't had a chance to test the side-effects of this hack - if anyone can explain why this is bad, comments are welcome!

Comments

Hey, I just hopped over to your web-site via StumbleUpon. Not somthing I would generally read, but I liked your thoughts none the less. Thanks for creating some thing worth reading.

There's a module that helps with this
http://drupal.org/project/ccl

This is a nice post in an interesting line of content.Thanks for sharing this article, great way of bring this topic to discussion.
http://www.sexaddiction.ie/

thank you for the very helpful information
This information really is very nice
thank you very much, Greetings from Obat Radang Amandel Tradisional Obat Radang Amandel Tradisional Obat Radang Amandel Tradisional and always success

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <apache>, <bash>, <c>, <cpp>, <drupal5>, <drupal6>, <java>, <javascript>, <php>, <python>, <ruby>. The supported tag styles are: <foo>, [foo]. PHP source code can also be enclosed in <?php ... ?> or <% ... %>.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.