Overview-approach to block visibility
As of Drupal 5.x you can specify what roles can see a block through the block admin UI, but using PHP still gives you extra flexibility.
If you are going to set visibility on a lot of blocks, see Block Page Visibility
Review of how the role visibility works in Drupal 5
- If no role check boxes are checked, block is visible to all roles.
- If "authenticated user" is checked, all logged in users will see the block, checking any of the other role boxes (other than anonymous user) is meaningless.
- Checking anonymous users means that logged-in users, unless they belong to another role that is also checked, will not see the block.
Basics of setting visability via PHP:
- Go to administer >> access control and ensure “administer blocks “ and “use PHP for block visibility” are checked for your role.
- Go to administer >> blocks and find the block you want to set the visibility for.
- Click “configure” next to that block.
- Under the section entitled, “Page specific visibility settings”, click the radio button for “Show if the following PHP code returns TRUE”
- In the text box provided, enter whichever of the following snippets meets your needs:
Sample Snippets
Show block only to logged in users:
(In Drupal 5 this is done by simply checking the "authenticated user" box.)
<?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:
(In Drupal 5 this is done by simply checking the box of the desired 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). (In Drupal 5 this is done by checking role checkboxes.)
<?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:
(This snippet is quite helpful in Drupal 5. If you want to show the block to authenticated users who have no other role but not to other authenticated users who do have a role, the checkboxes will be of no help.)
<?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 a block based on path. The following workaround is a bit complex and clunky, but it works.
- On the page administer >> blocks, hover over the configure link for the block you want to control in order to view the URL. Most of the URLs will end in “configure/sometext/somenumberortext”. Make a note of the “sometext” and the “somenumberortext”.
- Set the region for this block to "None". From now on let's call this block "Original Block."
- Go to administer >> blocks >> add block (tab) . In the block description field (what shows up on the admin/build/block page) write something like "Original Block Name Visible".
- Set the block body input type to PHP.
- What we do here, in the body (not in the visibility settings) is that we set the non page orientated visibility settings with php code. If the visability settings we set are TRUE -- then the code calls to output the actual content of our now disabled, original block. Pretty tricky huh! As an example, we are going to use a simple visability snippet. Start out with this shell in the block body text area:
- 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:
- Add in the block calling code so it looks like this:
- Replace with the “SOMETEXT” and “SOMENUMBER” that you noted in step 1.
- The final result should look something like this:
- 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” (you are still in this new block, not the original block) section and set one of the first two radio buttons as normal. Add the page specific setting in the usual place
- Enable and place this new block and check to see that the original one has its region set to "none". Make sure you don't delete the original one. That's where the content is coming from. Examine the block descriptions for both of them and describe them in a way that, hopefully, won't confuse you later. It's a good idea to add commenting to the php snippet explaining exactly what you've done.
<?php
global $user;
$output = '';
return $output;
?><?php
global $user;
$output = '';
if ($user->uid){
}
return $output;
?><?php
global $user;
$output = '';
if ($user->uid){
$block = SOMETEXT_block('view', SOMENUMBER);
$output = $block['content'];
}
return $output;
?><?php
global $user;
$output = '';
if ($user->uid){
$block = menu_block('view', 10);
$output = $block['content'];
}
return $output;
?>
I needed to show a block for
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
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 andstrpos()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
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
See also: How to control
See also:
For Drupal 6
modified for D6:
<?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))) {
$node = node_load(arg(1));
$terms = taxonomy_node_get_terms($node);
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;
?>
Do Not Show Block for Specific Node Type
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
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.<?phpglobal $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
Block to appear on user/1 but not user/1/edit or user/register
user/1, user/2, user/3, etc. Block shows
user/1/edit. Block doesn't show because arg(2) exists
user/register. Block doesn't show because arg(1) isn't numeric.
<?php/* this block will show on user/2 but not on user/register or user/2/edit. First arg must be "user", second arg must be a number, third arg must be empty. */
if ((arg(0) == 'user') && is_numeric(arg(1)) && (arg(2) == NULL)) {
return TRUE;
}
else {
return FALSE;
}
?>
visibility based on nodetype submission...?
i created a nodetype that is associated with a user's profile vis a vis the Content Profile module. i want to limit a block's visibility based on whether or not they have created that piece of content. so, for example, i have a nodetype called 'am_registration' which is associated to the user who created it. if they have already filled out this content type once, i do not want the block to show. because i only want this block to show up on one page, i have the code for it in the body section:
<?phpglobal $user;
if ($user->uid) {
if ($user->am_registration) {}
?>
<div id="register-button">
<p><h5>Congratulations! You are logged into the site!</h5></p><p><h4><a href="/node/add/am-registration">To proceed in your registration, please click here.</a></h4></p><p> </p><p> </p>
</div>
<?php
}
?>
it works in terms of becoming invisible when the user is not logged in (if ($user->uid)) but the next embedded if statement doesn't seem to be doing a damn thing...
ideas?
awillem
block visible for specific content type
if ($node = menu_get_object()) {
return($node->type=='agent' || $node->type=='exhibition')
}
--
keine zeit für spielkonsolen mein leben ist jump n run!
valderama.net
add missing semicolon and it works perfectly
Hi, thanks for the 6x snippet above, it's working great for me. The only snag I hit was that the "return" line is missing a semi-colon at the very end of the line. After adding the semicolon it started working.
Steve
Revista Y AHORA QUÉ | Selectividad - Universidades - Foro Blog Chat Estudiantes