This issue seems to keep coming back, so I figured it was time to submit a feature request. The option "Show on only the listed pages" in the block configuration's "Page specific visibility settings" is very useful, but I often find that I need a way of specifying exceptions to this rule, for which I end up writing code.

This is what I propose for "Page specific visibility settings" in block configuration:

Show block on specific pages:
* Show on every page.
* Show on only the listed pages.
[input box]

Exceptions
* Do not show on the listed pages.
[input box]

This way, you can not only specify exceptions to "Show on every page" but also to "Show on only the listed pages."

Logic:
"Show on every page" - show on every page except those that match "Exceptions"
"Show on only the listed pages" - show on only the pages listed in "Pages," except those that match "Exceptions"
If "Show on only the listed pages" is selected and the "Pages" box is empty, the block is never displayed.
Show if the following PHP code returns TRUE (PHP-mode, experts only) - show if the PHP code in "Pages" returns TRUE, except for those pages that match "Exceptions" (hey, why not?)

This feature, combined with the new role-based block display feature, should maximize the flexibility of block configuration.

Comments

Version:5.x-dev» 6.x-dev

I like this idea, but it will have to wait until 6.x. Will come back to this once D5 is out.

Version:6.x-dev» 7.x-dev

Suppose this issue could be closed

Version:7.x-dev» 8.x-dev

why? it is not solved yet..

I create a MODULENAME_block_include_exclude( $include, $exclude ) function, using the code here: http://drupal.org/node/645438, then I create dedicated functions for each block that needs one that calls this new function, and insert calls to those into the PHP option in Block Visibility.

So I wind up with something like this:

<?php
function MODULENAME_display_somesection_sidebar(){
  return
MODULENAME_include_exclude_block( 'include/pattern/*', 'exclude/pattern/*' );
}
// for PHP block visibility, able to combine include/exclude conditions (standard format, one per line)
// from drupal.org/node/645438
function MODULENAME_include_exclude_block( $include, $exclude ){
 
$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($include, '/')) .')$/';
  if (
preg_match($regexp, $path)) {
   
$regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote($exclude, '/')) .')$/';
    if (!
preg_match($regexp, $path)) {
     
$match = TRUE;
    }
  }
  return
$match;
}
?>

Then in Block Visibility, all you put in the PHP field is:

<?php
return MODULENAME_display_somesection_sidebar();
?>

You could also call the include_exclude() function directly from the PHP field, but creating dedicated helper functions for complex blocks has the advantage of putting all the logic in your module.