Block visible for Specific Content Type AND Specific URL
Site administrators · Site users · Themers · Drupal 5.x · Drupal 6.x · Drupal 7.x · No known problems
Last modified: June 29, 2009 - 21:05
I wanted to have a block displayed for a specific content type but also displayed on a number of pages.
The solution is to create a single Block and choose PHP for visibility settings.
The PHP code goes as follows:
<?php
$match = FALSE;
$types = array('content-petites_annonces' => 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 (substr($_SERVER["REQUEST_URI"], 0, 10) == '/petitesan')
{ $match = TRUE;}
if (substr($_SERVER["REQUEST_URI"], 0) == "/node/add/content-petites_annonces
")
{ $match = TRUE;}
return $match;
?>Basically the first part put $match to TRUE if the page is of the content type I want. The other 2 if statements are selection based on the URL of the page allowing me to activate the Block for the URL I want.
Note that Drupal 7 will reintroduce a GUI for block visibility by content type, which reduces dependency on snippets like this one.

Block visibility for node type and URL selection
Here's a more concise example which shows the block only on pages of specific node type and on the taxonomy pages. Tested on Drupal 5.x. Note the use of node_load argument and the arg() function for URL selection.
<?php
$match = FALSE;
$types = array('product' => 1);
if ((arg(0) == 'node') && is_numeric(arg(1))) {
$node = node_load(arg(1));
$match = isset($types[$node->type]);
}
$match |= ((arg(0) == 'taxonomy') && (arg(1) == 'term'));
return $match;
?>
Nice example. I adapted it
Nice example. I adapted it to show a block where either the URI is "/foo" or "/bar" or the node is of type "project". In the interest of platform independence, I used the request_uri() function.
If you needed to match a wildcard, this could be adapted by adding one of the regular expression functions.
<?php
$match = FALSE;
$types = array('project' => 1);
$uris = array('/foo' => 1, '/bar' => 1);
if ((arg(0) == 'node') && is_numeric(arg(1))) {
$node = node_load(arg(1));
$match = isset($types[$node->type]);
}
$match |= isset($uris[request_uri()]);
return $match;
?>
Hide block on node edit page
Here is an example for hiding a block on a node's edit page.
<?php
$match = TRUE;
$url = request_uri();
if (strpos($url, "edit")) {
$match = FALSE;
}
return $match;
?>
Block visibility on other pages can be controlled by adding additional if statements. This example hides block on "/admin/*", "/filter/tips", "/node/add", and "node/10" pages.
<?php
$match = TRUE;
$url = request_uri();
if (strpos($url, "admin")) {
$match = FALSE;
}
if (strpos($url, "filter/tips")) {
$match = FALSE;
}
if (strpos($url, "node/add")) {
$match = FALSE;
}
if (strpos($url, "edit")) {
$match = FALSE;
}
if (strpos($url, "node/10")) {
$match = FALSE;
}
return $match;
?>
I'm sure the code could be more efficient but would take away from showing the concept.
HTH,
Doug
Thanks for the snippet! I
Thanks for the snippet! I had searched for a while trying to figure out how to handle php block visibility to show on a list of specific pages and also page(s) with multiple conditions, like url=FOO and user_is_logged_in. This snippet helped me do it.
Here is my modified snipped that resolved my particular needs:
<?php
$url = request_uri();
$show_pages = array('account','library','search','myaccount','myaccount',);
foreach ($show_pages as $vis_page) {
if (strpos($url, $vis_page)) {return TRUE;}
}
// Multi-condition visibility
if (strpos($url, "user") && user_is_logged_in()) {
$match = TRUE;
}
return FALSE;
?>
Complete Computer Care
Block visible for Specific Content Type AND Specific URL
URLs to show block are in $path variable. It is possible to use '*' in URL.
Node types are in $types variable.
Block will show on one of URLs from $paths variable or where type of node is one from $types variable.
<?php
$paths = "forum\r\nforum/*\r\nuser\r\nuser/*\r\nadmin\r\nadmin/*";
$types = array('forum' => 1);
$match = FALSE;
$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($paths, '/')) .')$/';
if (preg_match($regexp, $path)) {
$match = TRUE;
}
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;
?>
Another way to do it
I wanted a template function to identify types of content so users know whether they're editing a page, blog, image, etc.
I'm not an elegant coder, but the following worked for me,
function Sp0xx_is_ID($nid) {$page = array('page' => 1);
$story = array('story' => 1);
$image = array('image' => 1);
$blog = 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($page[$type])) {
$output .= 'This is a Page.';
}
if (isset($story[$type])) {
$output .= 'This is a Story.';
}
if (isset($image[$type])) {
$output .= 'This is an Image.';
}
if (isset($blog[$type])) {
$output .= 'This is a Blog.';
}
}
return $output;
}
[[[ ALL HAIL THE ALMIGHTY GOOGLEBOT ]]]
content type + url with wildcard
Here's how my hacker husband adapted the script to accommodate a content type ("photo") and a url with a wildcard (/photos/*):
<?php
$match = FALSE;
$types = array('photo' => 1);
if ((arg(0) == 'node') && is_numeric(arg(1))) {
$node = node_load(arg(1));
$match = isset($types[$node->type]);
}
$match |= (ereg('/photos(/.*)?', request_uri()) != 0);
return $match;
?>
The opposite snippet
If you want a snippet that shows blocks on specific content types but hides the block on specific URLs, then follow up on that specific page. Here: http://drupal.org/node/502480