On Drupal site A we have a bunch of links to non-Drupal site B. For marketing and tracking purposes all these links have a different URL variable appended to them, so that when a user registers on site B we can determine where on site A they came from.

At the moment I use page.tpl.php to create the variable ($forceCode) but it now transpires I need this variable to be available to node.tpl.php too, and I feel like there must be a less hacky and more universal way of doing this, probably using a preprocess function in template.php that right now seems beyond my comprehension level.


$specialPages is an array of node IDs that need a special code.
$specialFolders is an array of taxonomy IDs that need a special code.

  • If the current node ID matches any in the nid array, I set the variable accordingly.
  • If not then I get the category (taxonomy) of the current node, or if the current page is a taxonomy term itself then use its own tid.
    • Then using this taxonomy ID I get all other tids that are parents of that tid.
    • Then I look for matches of any of these taxonomy IDs in my array of special tids in order to set the variable.
  • If the current page has not matched any of my special nodes or taxonomies, the variable remains its default value.


// we later restrict our parent taxonomy search to certain types but it's not strictly necessary
$contentTypes = array("article","advpoll","event");

$specialFolders = array(
    276 => "events",
    292 => "free-dating",
    498 => "date-explorer"
$specialPages = array(
    22 => "reviews",
    86 => "texting"

$forceCode = "default";

// check for specific page first
if (@array_key_exists($node->nid,$specialPages)){
    $forceCode = $specialPages[$node->nid];
} else {
    // there was no entry for this nid, let's check parent terms
    $parentTerms = array();
    $hasParents = false;
    if (arg(0) == "taxonomy") $hasParents = arg(2);
    if (@in_array($node->type,$contentTypes)) {
        $category = field_view_field('node', node_load($node->nid), 'field_category');
        $hasParents = $category['#items'][0]['tid'];
    if ($hasParents !== false) {
        $parents = taxonomy_get_parents_all($hasParents);
        foreach ($parents as $term){
            $parentTerms[] = $term->tid;

    foreach ($parentTerms as $tid){
        if (array_key_exists($tid,$specialFolders)){
            $forceCode = $specialFolders[$tid];
  • Are you looking for the generic hook_preprocess() perhaps? – Clive Apr 14 '15 at 13:30
  • Perhaps Clive - I've tried messing with it for an hour since you said that but not got far. I've tried: function hook_preprocess(&$variables, $hook){ $variables['myNewVar'] = "anything"; } has not lead to me being able to access $myNewVar from either page.tpl.php or node.tpl.php on any type of page. Also tried by prefixing function with themename. – Matt Morrison Apr 14 '15 at 14:32

I've found a very satisfactory solution using function matchtheme_preprocess(&$variables, $hook) which will always supply variables to page and node templates.

The more complicated bit was finding an appropriate way to get this function to collect the data I need (nid or tid) properly regardless of whether it was the page or node template making the call.

Essentially (this is the cut down version) I just did this:

if ($hook == "page"){
    // supplies variables to page.tpl.php
    // the page template can cover anything, including a node and taxonomy
    if (arg(0) == "node"){
        $nidToCheck = arg(1);           
    } else if (arg(0) == "taxonomy"){
        // already a taxonomy page, the term id is the category
        $hasParents = arg(2);
} else if ($hook == "node"){
    // supplies variables to node.tpl.php
    $nidToCheck = $variables['elements']['#node']->nid;

From there if ($nidToCheck) allows me to use the nid to generate $hasParents for nodes, and then I can move on handling all nodes and taxonomy terms to do what I want (all this bit is essentially the same as in my question).

Finally I feed back to the template an array of variables in much the same way as they were set before.

So glad to have this sorted as it caused quite a headache. Would love to hear whether or not this is an efficient or clever way of dealing with it. The most obvious issue to me is that the array of variables (and of course the whole function) will get run twice on node pages - once for the page template and once for the node template - which is a touch inefficent. I guess I could contain the whole thing in an if (!isset...

| improve this answer | |

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.