Overview-approach to block visibility

Note: As of 5.x you can specify what roles can see a block through the block admin UI, but using PHP gives you extra flexibility.

  1. Go to administer >> access control and ensure “administer blocks “ and “use PHP for block visibility” are checked for your role.
  2. Go to administer >> blocks and find the block you want to set the visibility for.
  3. Click “configure” next to that block.
  4. Under the section entitled, “Page specific visibility settings”, click the radio button for “Show if the following PHP code returns TRUE”
  5. In the text box provided, enter whichever of the following snippets meets your needs:

Show block only to logged in users:

<?php
global $user;
if (
$user->uid){
  return
TRUE;
} else {
  return
FALSE;
}
?>

Variation: “if (!$user->uid){“ will show block only to anonymous users.

Show block only to a particular role:

<?php
global $user;
if (
in_array('Approved Role',$user->roles)) {
  return
TRUE;
} else {
  return
FALSE;
}
?>

Variations: Replace "Approved Role" with whichever role you want to view it. Or use !in_array to hide it for that role.

Show block set of roles:

(Thanks Chris Herberte)

<?php
global $user;
$allowed = array('moderator','administrator');
$valid=FALSE;
foreach(
$user->roles as $role){
  if(
in_array($role, $allowed)) {
   
$valid=TRUE;
  }
}
return
$valid;
?>

Don't show block set of roles:

<?php
global $user;
// These are the roles who should not see this block
$notallowed = array('anonymous user','artist','GoZabo Administrator', 'SuperAdmin');

// Assume they can see it to start
$valid=TRUE;

// Go through each role the user is in and, if we hit a role that is not allowed to see it, set valid to false
foreach($user->roles as $role){
  if(
in_array($role, $notallowed)) {
   
$valid=FALSE;
  }
}

// If no roles were hit that aren't allowed, this will still be true. Otherwise it will be false.
return $valid;
?>

Show block only to a particular user:

<?php
global $user;
if (
$user->uid == 1){
  return
TRUE;
} else {
  return
FALSE;
}
?>

Variations: Replace the “1” with any UID.

Show block only for specific content type:

<?php
$match
= FALSE;
$types = array('story' => 1, 'page' => 1);
if (
arg(0) == 'node' && is_numeric(arg(1))) {
 
$nid = arg(1);
 
$node = node_load(array('nid' => $nid));
 
$type = $node->type;
  if (isset(
$types[$type])) {
   
$match = TRUE;
  }
}
return
$match;
?>

Variations: This example would show the block on all 'story' and 'page' type nodes. Just change line 2 - the $types array - to indicate which node types you want your block to appear on. Use the format 'nodetype' => 1 for each type you need. And yes, the array can hold single type only.

Combining PHP visibility control with specific page visibility:

When you choose the option to control visibility by PHP, you lose the ability to have Drupal automatically show/not show based on path. This workaround is a bit complex and clunky, but it works.

  1. On the page administer >> blocks, hover over the configure link to view the URL. Most of the URLs will end in “configure/sometext/somenumber”. Make a note of the “sometext” and the “somenumber”.
  2. Go to administer >> blocks >> add block (tab) . This new block will become the block that is shown so title it appropriately.
  3. Set the block body input type to PHP.
  4. Start out with this shell in the block body text area:
  5. <?php
    global $user;
    $output = '';

    return
    $output;
    ?>

  6. Paste in just the “if” part from one of the snippets above. We’ll use the first snippet as an example. You should have something like this:
  7. <?php
    global $user;
    $output = '';

    if (
    $user->uid){
    }

    return
    $output;
    ?>

  8. Add in the block calling code so it looks like this:
  9. <?php
    global $user;
    $output = '';

    if (
    $user->uid){
    $block = SOMETEXT_block('view', SOMENUMBER);
    $output $block['content'];
    }

    return
    $output;
    ?>

  10. Replace with the “SOMETEXT” and “SOMENUMBER” that you noted in step 1.
  11. The final result should look something like this:
  12. <?php
    global $user;
    $output = '';

    if (
    $user->uid){
    $block = menu_block('view', 10);
    $output $block['content'];
    }

    return
    $output;
    ?>

  13. That takes care of showing the block only to logged in users (or whatever snippet you used). Next go to the “Page specific visibility settings” section and set one of the first two radio buttons as normal.
  14. Enable and place this new block and disable the old one. You may find it helpful to change the title on the original block to differentiate them.

I needed to show a block for

v1nce - August 8, 2007 - 15:30

I needed to show a block for specific content type as well as specific url aliases.

I believe I read the arg(0) function doesn't work correctly for all content types so I combined this with $_SERVER['REQUEST_URI'] that works well:

if (arg(0) == 'faceted_search' || $_SERVER['REQUEST_URI'] == '/collections') {
  $match = TRUE;
}

Here is the combined snippet:

<?php
$match
= FALSE;
$types = array('collection_item' => 1);
if (
arg(0) == 'node' && is_numeric(arg(1))) {
 
$nid = arg(1);
 
$node = node_load(array('nid' => $nid));
 
$type = $node->type;
  if (isset(
$types[$type])) {
   
$match = TRUE;
  }
}

if (
arg(0) == 'faceted_search' || $_SERVER['REQUEST_URI'] == '/collections') {
 
$match = TRUE;
}
return
$match;
?>

-----------------------------------------------------------------
Petafoo - We Love Animals

maybe better

zuk0 - September 13, 2007 - 18:22

The following code is just slightly modified v1nce's snippet.

Changes:
I use Drupal request_uri() function instead of $_SERVER['REQUEST_URI'] to get URL of current page and strpos() to show block when this URL contains specified word ("blog" in this case; you can change it on line 13).

<?php
$match
= FALSE;
$types = array('blog' => 1);
if (
arg(0) == 'node' && is_numeric(arg(1))) {
 
$nid = arg(1);
 
$node = node_load(array('nid' => $nid));
 
$type = $node->type;
  if (isset(
$types[$type])) {
   
$match = TRUE;
  }
}
$url = request_uri();
if (
strpos($url, "blog")) {
 
$match = TRUE;
}
return
$match;
?>

Visibility set to TRUE based on taxonomy term OR url

Shai - May 9, 2008 - 03:12

Here is another snippet cut and paste. This one combines the need to make a block visible based on a node's taxonomy term OR the presence of a string in part of the URL. I have a topic area of a site which includes nodes and views and I needed the block to show both the nodes (based on taxonomy term) and views (based on a portion of the path).

Note: I'm a relatively new coder. Not only do I like comments in code, but I also like verbose semantically oriented names for variables. I know a lot of coders like to use short variable names. Here the variable names are long and verbose and hopefully make the code easier to understand.

<?php
 
//code snippet for causing block to show based on a node's taxonomy term OR on a designated string in the url.
 
$make_block_visible = FALSE;
 
$term_id_to_trigger_show_block = 21; // replace '21' your term id.

 
if ((arg(0) == 'node') && is_numeric(arg(1))) {
   
$terms = taxonomy_node_get_terms(arg(1));
    foreach(
$terms as $term) {
      if (
$term->tid == $term_id_to_trigger_show_block) {
        
$make_block_visible = TRUE;
      }
    }
  }
 
// The following code will cause block to show on the designated term's built-in "view" page such as:
  // example.com/taxonomy/term/21
 
if ((arg(0) == 'taxonomy') && (arg(1) == 'term') && (arg(2) == $term_id_to_trigger_show_block)) {
   
$make_block_visible = TRUE;
  }

 
// the following code causes the block to show any time the designated string
  //(replace 'panim' with your string) appears in the url
   
$url = request_uri();
    if (
strpos($url, 'panim')) {
     
$make_block_visible = TRUE;
    }
    return
$make_block_visible;

?>

Shai Gluskin
content2zero.com

Do Not Show Block for Specific Node Type

WisTex - February 20, 2008 - 15:46

Here is a variation of the code posted above. This time it prevents the block from being shown for specific node types, in this case story and page.

<?php
$match
= TRUE;
$types = array('story' => 1, 'page' => 1);
if (
arg(0) == 'node' && is_numeric(arg(1))) {
 
$nid = arg(1);
 
$node = node_load(array('nid' => $nid));
 
$type = $node->type;
  if (isset(
$types[$type])) {
   
$match = FALSE;
  }
}
return
$match;
?>

--
Scott M. Stolz
http://www.wistex.com/

specific content type if current user is author

goldschmidt.a - May 7, 2008 - 01:54

Combining a couple of methods shown above and using the conditional statement if ($user->uid == $node->uid), I created this code to only show a block when the node is a certain content type (page) AND the viewer is also the author of the node.

<?php
global $user;
$match = FALSE;
$types = array('page' => 1);
if (
arg(0) == 'node' && is_numeric(arg(1))) {
 
$nid = arg(1);
 
$node = node_load(array('nid' => $nid));
 
$type = $node->type;
  if (isset(
$types[$type])) {
    if (
$user->uid == $node->uid) {
       
$match = TRUE;
    }
  }
}
return
$match;
?>

Sincerely,
Andrew G

 
 

Drupal is a registered trademark of Dries Buytaert.