I'd like to display a certain block (the events calendar block in case it matters) only when users are in a certain book on my website (the 'book' that deals with our community activities, signing up, past event reports etc).

Is there a simple PHP snippet I can use to detect if the page being displayed is in the book whose root node ID is some value?

Or, perhaps a different approach.

Is there a simple PHP snippet I can use to detect which Primary Nav bar tab the page is in? (Each tab corresponds approximately to a different book). Then I could just have the Event module display when the user is in a certain tab.

thx, michael

Comments

Chill35’s picture

It may be too late for this but...

When I create a book, I usually give all sections of the book the following url alias : book_name/section_name

So I can access section1 at book_name/section1_name
and have section2 at book_name/section2_name
and I can access the book 'cover' at book_name

Now...

For the block visibility, I would use php and...

if (arg(0) == "node" && is_numeric(arg(1))) { 
  $alias = drupal_lookup_path('alias', arg(0) . '/' . arg(1));
  if ($alias) {
    $bookName = explode('/', $alias)[0];
    if ($bookName == 'blabla') {
      return true;
    } else {
      return false;
    }
  }
} 

I am sure there is another way though...

Caroline
A coder's guide to file download in Drupal
Who am I | Where are we
11 heavens

Chill35’s picture

A full-proof way is to look up the database.

if (arg(0) == "node" && is_numeric(arg(1))) {
  $result = db_query("SELECT parent FROM {book} WHERE nid = %d", arg(1));
  if ($result == YOU_BOOK_NID) {
    return true;
  } else {
    return false;
  }
} else {
  return false;
}

I forgot to return false in my other snippet in the case where we are not on page with internal path node/nid.

Caroline
A coder's guide to file download in Drupal
Who am I | Where are we
11 heavens

mikemee’s picture

Thanks Caroline. You got me started but the code didn't quite work. This does seem to work however. Note that the node ID of the book I'm checking against is 46, so others should substitute as need be:

<?php
if (arg(0) == "node" && is_numeric(arg(1))) {
  if (46 == arg(1)) {
    return TRUE;
  }
  $result = db_fetch_object(db_query("SELECT parent FROM {book} WHERE nid = %d", arg(1)));
  if (46 == $result->parent) {
    return TRUE;
  } else {
    return FALSE;
  }
} else {
  return FALSE;
}
?>

Not sure how important the upper case TRUE/FALSE is, but the extra db_fetch_object was critical. Perhaps there's a better way as the result should be a singleton.

thanks again! michael

Chill35’s picture

true or TRUE, it does not matter in php. My guess is that even when getting a single value (one column with one value in that column, no 'object' per say), we still have to use db_fetch_object.

I always use db_fetch_object in my code anyway, because I am not a Mysql-in-Drupal expert... That's what I put first up there, then edited myself. Actually my first trial was too wordy (using b without necessity) :

$result = db_fetch_object(db_query("SELECT b.parent FROM {book} b WHERE b.nid = %d", arg(1)));

That's first rate code you have there. :b <--- that's me drooling

Thanks for sharing!

Caroline
A coder's guide to file download in Drupal
Who am I | Where are we
11 heavens

Mojah’s picture

<?php
if (($node->parent=="42") || ($node->nid=="42")) {
return=TRUE;
}
?>

$node->parent is loaded by default me believes so you may use that instead of making a query. The Book nid will be 42 and all child pages will have $node->parent = 42

One Love

ryborg’s picture

blocks don't load the node, hence the arg and nid approach. this will do what you want, but only works in Drupal 6.
parent method will work, but only two levels deep. you'll have to add a bit more logic if you want it to work with children of children.

<?php 
if (arg(0) == 'node' && is_numeric(arg(1))) {
  $nid = arg(1);
  $node = node_load(array('nid' => $nid));
if ($node->book['bid']==41) {
return TRUE;
}
else {
return FALSE;
}
}

?>
mikemee’s picture

I've added this to the PHP tricks section of the docs: http://drupal.org/node/125380 - please update there if you think its appropriate. Thanks!

Chill35’s picture

That's great :) I looked at the page. That code is top notch.

Caroline
Who am I | Where are we
11 heavens

evelien’s picture

this would only work for the top level and first level. Not if you do have more levels (like book title - chapter - paragraph. This would only show up at title and chapter, not at paragraph pages)

biggena’s picture

I have modified this script to support more than 2 levels of book hierarchy.

Note, you need to replace 46 with your own book id (the most top level book node).

$book_id = 46;

if (arg(0) == "node" && is_numeric(arg(1))) {
  $current_nid = arg(1);
  if($book_id == $current_nid) {
    return TRUE;
  }
  // Get parent book (recursion)
  while(true) {
    $result = db_fetch_object(db_query("SELECT bid FROM {book} WHERE nid = %d", $current_nid));
    if( $result === FALSE ) {
      return FALSE;
    }
    else if ($book_id == $result->bid) {
      return TRUE;
    }
    else {
      $current_nid = $result->bid;
    }
  }
}
else {
  return FALSE;
}

This code works on Drupal 6.

stefan81’s picture

Hi
It's slightly off topic, but I just need to check if the page belongs to a book (no specific, any book ok).

So maybe we can work with

if (empty($current_nid)) {
    return TRUE;
  }

But unfortunately I can't code php.
So I would be happy for a suggestion.

Thanks for your help :)

stefan81’s picture

If possible, I would like to combine it with:

<?php
  $match = FALSE;
  
  // block is visible on the content types entered here 
  $types = array('page' => 1);
  $url = request_uri();

  if ((arg(0) == 'node') && is_numeric(arg(1))) {
    $node = node_load(arg(1));
    $match = isset($types[$node->type]);
  }
  // block is invisible on URLs entered here
  if (strpos($url, "comment")) {
    $match = FALSE;
  }  
  if (strpos($url, "edit")) {
    $match = FALSE;
  }  
   if (strpos($url, "admin")) {
    $match = FALSE;
  }
  return $match;
?>

Thanks a lot for your help :)