Passing variables between different Drupal hooks using context API

Posted Nov 14, 2011 // 2 comments
Felix :

Drupal’s nature of using hooks to allow functionality to be overridden by contributed modules makes it difficult to make data available between different hook implementations during the request process, especially if they are overridden. Simply put, we need to have certain values available system-wide once they are set.

For instance, Views block display defines an RSS link, but once the page template in the theme is reached that information is long gone. If we needed to have the RSS be the current page’s feed link, then we would require a complex (and sometimes risky) implementation. But the Context API offers a set of functions that makes life really easy in these situations: context_set, context_isset, and context_get.

First, figure out what information you need, from where, and very importantly, through what hook, if any, can you reach that variable. For example in a View, an attached feed url+icon can be obtained by using hook_views_pre_render.

It is important to determine if the value is already available or not. Then determine where the information is available, and if there is a hook to access that variable. In my case, I needed that information in the page template, or for that matter, the hook_page_preprocess function, because by the time the process reaches this stage the view will be long gone.

In your theme template.php file, your custom module, or feature, define a hook function at the moment your variable is available. For instance:

<?php
function mytheme_views_pre_render(&$vars) {
  switch (
$vars->name){
    case
'my_view':
      if (isset(
$vars->feed_icon) && !empty($vars->feed_icon)){
     
context_set('mytheme_page_feed', 'page_feed_icon', $vars->feed_icon);
    }
    break;
  }
}
?>

The variable must be now set in the context you want, so we can to use it as needed. For instance, create a hook (if it doesn’t exist) or just add the extra code to an existing one. For example:
<?php
function mytheme_preprocess_page(&$variables) {
  if (
context_isset('mytheme_page_feed', 'page_feed_icon')){
   
$variables['page_feed_icon'] = context_get('mytheme_page_feed', 'page_feed_icon'));
  }
::
::
}
?>

Now you can use the variable $page_feed_icon in your template page.
Notice the use of the hooks, and make sure they are used in the proper sequence. Also, the use of the functions: context_set, context_isset, and context_get, which:

See API.txt in the context module
Context provides a centralized set of API functions for setting and retrieving a static cache:
// Set a static cache value at [my_namspace|my_namspace][mykey]
context_set('my_namespace', 'mykey', $value);

// Retrieve a static cache value at [my_namespace|my_namespace][mykey]
context_get('my_namespace', 'mykey'); // $value

// Boolean for whether there is a value at [my_namespace|my_namespace][mykey]
context_isset('my_namespace', 'mykey'); // TRUE

These are used internally by context, but may also be used by other modules. Don’t use the namespace `context` unless you want to affect things that context is up to.

An obvious but never overrated advantage is that you will have code that is more clean, less prone to errors, and less repetitive.

About Felix

Felix Silberstein, developer, has been doing software development since high school (a common refrain among Phase2 developers)! And for the last 4 years, Felix has been focusing his attention on developing his capabilities in Drupal and ...

more >

Read Felix 's Blog

Comments

by Tanc (not verified) on Wed, 11/16/2011 - 02:35

Thank you

Thanks, this has made my day. Such a nice easy way of passing variables around when theming.

by fsilberstein on Mon, 11/28/2011 - 11:17

Pretty cool, yes.Thank you.

Pretty cool, yes. I'm glad it helped you too. Thank you.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
  • Allowed HTML tags: <a> <strong> <code> <p> <img> <ul> <ol> <li> <h2> <h3> <h4> <b> <u> <i>
  • You may insert videos with [video:URL]

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.