Using Active Contexts In Drupal 7

Context is a Drupal module that allows you to set up reactions that fire when certain conditions are met. This might be when a certain path is loaded, or when a particular content type page is viewed, or even on every page on a site. When the conditions are met a number of reactions can be fired, which include placing blocks, setting breadcrumbs, or just adding a class to the page template.

I use the Context module extensively in my projects as they provide a better way of controlling the placement of blocks than the default Drupal blocks admin pages. One of the most important differences is that Context allows for the same block to be placed into two different regions on a site, which is something Drupal can't do out of the box. More importantly, Contexts are exportable and fully integrate into Features. This means that I can setup a collection of Contexts on my development environment and package them into a Feature that I can then deploy to the live site and not have to manually setup the placements of blocks.

I often find myself wanting to get Drupal to react to something that I have already set up as a Context but which Context doesn't have a reaction for. Rather than integrate with the Context API directly and create a reaction plugin I will often just detect that the Context has been activated and act accordingly. This is to do things like altering theme templates suggestions or to tweaking classes on certain components and so creating a reaction plugin isn't necessary. It is also often easier to set up a Context for a particular situation without having to write lots of code to detect it. All of the detection mechanisms within Context are well tested and have normally been run so there is little point repeating functionality.

To use an existing Context in your code you need to call the function context_active_contexts(). From this you will get an array of Contexts that have been activated for that page. The keys of this array are the machine names of the active Contexts so a quick inspection of the array keys can show if the Context you are interested in is active. From here you can then do whatever you need to do.

The following example grabs the active Contexts and looks to see the 'news' Context is active. If it is then the page--news.tpl.php template is used to render the page. The Context in question is checking for more than the content type here, it is also looking at a series of news views that show the news in different ways.

function MYTHEME_preprocess_page(&$vars) {
  $active_contexts = context_active_contexts();
  if (in_array('news', array_keys($active_contexts))) {  
    $vars['theme_hook_suggestions'] = array('page__news');
  }
}

In order to achieve the same effect without using Context the following code would be needed. This way of detecting the current content of the page is (in my opinion) slightly more complex to understand. Also, since Context has already done all the work in detecting the correct page then we are largely repeating that functionality here.

function MYTHEME_preprocess_page(&$vars) {
  if ((isset($vars['node']) && $vars['node']->type == 'news')
    || (isset($vars['view']) && $vars['view']->id == 'news')
  ) {  
    $vars['theme_hook_suggestions'] = array('page__news');
  }
}

Add new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
2 + 6 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.