Block visible for specific nodes/terms and their children

I really wanted to create multiple image galleries and for each gallery have a different menu. It was also necessary to display this menu for all child galleries and images. I didn't particularly feel like adding each node to the pages box on the configure menu block screen, as the number of images and galleries would be growing all the time. I decided that I needed block inheritance, so I created my own includes file to contain functions to do this for me. It's a bit messy and may not suit everyone's taxonomy structure, but it meets my needs.

Steps
1. Set up your menu / block.

2. Set the "page specific visibility settings" to be "Show if the following PHP code returns TRUE" on the block configuration screen.

3. In the "Pages" field, put something similar to the following:

<?php
include_once "./includes/inherit_blocks.inc";

if (
check_path("node/1")) return TRUE;

return
inherit_display_block(123);
?>

The first line just includes the file containing the functions. The check_path() function is for those nodes that you just want to hardcode the paths for, while the last line calls the function which handles the inheritance for tid 123.

4. Create the inherit_blocks.inc file and add the following:

<?php
function inherit_display_block($tid = 0) {
 
$is_child = FALSE;
  if (
$tid != 0) {
   
$this_page = drupal_get_path_alias($_GET['q']);
   
$url_parts = split("/", $this_page);
   
$num_parts = count($url_parts);

    if (
$url_parts[$num_parts-2] == "tid") {
     
$this_tid = $url_parts[$num_parts-1];
      if (
$this_tid == $tid) return TRUE;
     
$is_child = get_child_tids($tid, $this_tid);
    } elseif (
$url_parts[$num_parts-2] == "node") {
     
$this_node = $url_parts[$num_parts-1];
     
$is_child = check_child_node($tid, $this_node);
    }
  }


  return
$is_child;
}

function
get_child_tids($parent, $tid) {
 
$child = false;
 
$result = db_query("select tid from term_hierarchy where parent=$parent");
  while (
$child_tid = db_fetch_object($result)) {
    if (
$tid == $child_tid->tid) return true;
   
$child = get_child_tids($child_tid->tid, $tid);
    if (
$child) return true;
  }
  return
false;
}


function
check_child_node($parent, $node) {
 
$child = false;
 
$result = db_query("select tid from term_node where nid=$node");
  while (
$node_tid = db_fetch_object($result)) {
   
$tid = $node_tid->tid;
   
$result2 = db_query("select tid from term_hierarchy where parent=$parent");
    while (
$child_tid = db_fetch_object($result2)) {
      if (
$tid == $child_tid->tid) return true;
     
$child = get_child_tids($child_tid->tid, $tid);
      if (!
$child) return true;
    }
  }
  return
false;
}

function
check_path($path) {

 
$this_path = drupal_get_path_alias($_GET['q']);

 
$regexp = '/^'. preg_replace(
    array(
'/(\r\n?|\n)/', '/\\\\\*/''/(^|\|)\\\\<front\\\\>($|\|)/'),
    array(
'|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'),
       
'/') .'\2'), preg_quote("$path", '/')) .'$/';

  return
preg_match($regexp, $this_path);
}

?>

 
 

Drupal is a registered trademark of Dries Buytaert.