4

For example I end up with url's like

example.com/viewname?f=[0]field_name=%3A21

I want to make a block visible on pages like the above but not when only the view is displayed.

Only the view will looks like this: example.com/viewname

So my thought was to set the block visibility setting to be only visible on:

example.com/viewname*

That didn't work ( block did not show up ) so i tried:

example.com/viewname?* , example.com/viewname?f* and example.com/viewname/*

No success.

EDIT:

There are some options:

1) Creating a block in custom module could be a solution.

1a Setting visibility to 'none' by unsetting the block content and title ( which I have chosen to use for now )

1b Enabling the PHP filter module and adding a block setting visibility restrictions like so:

/**
  * Implements hook_block_info().
  */
function mymod_block_info(){
  $blocks['mymod_job_agent'] = array(
    'info' => t('block description'), //The name that will appear in the block list.
    'cache' => DRUPAL_CACHE_PER_ROLE, //Default
    'region' => 'sidebar_first', // assign block region
    'status' => 1, // enable the block
    'visibility' => BLOCK_VISIBILITY_PHP, // set visibility to use the result of pages
    'pages' => '<?php return TRUE; ?>',
  );
  return $blocks;
}

Drawback: since hook_block_info is called upon module install only you cant change your code without reinstalling the module. And putting php code in de pages just doesn't feel right. So I think we can cross option 1b.

2) Another solution would be to use the Block Conditional Visibility by URI Query Parameters module but I couldn't figure out how to use this for this use case.

Reading the comments this is something that should be done in the theme layer...

Hope this helps anyone searching for a similar question. feel free to edit update my question/answer to improve it!

3
  • 1
    Block visibility only checks the path part of a URL so you can't detect the presence of a query in this way. You could use PHP to do it. The cleanest way to do that would be in a custom module but you could also use a PHP visibility setting for the block. Commented Apr 22, 2013 at 9:27
  • So in a custom module I should create a block ( or hook the bock but when already creating a custom module ... ) And then check the $_SERVER string?
    – FLY
    Commented Apr 22, 2013 at 9:38
  • Essentially, depends how deep you want to go with this. You could directly probe the view object to see which URL variables apply for your search if you want to make it tighter. Commented Apr 22, 2013 at 9:41

4 Answers 4

4

You can use the Block Conditional Visibility by URI Query Parameters module to control block visibility via query string.

Controls block visibility by URI Query Parameters. Drupal natively allows blocks to be placed on pages by using their paths, however, this module allows administrators to also display modules based on url query parameters.

0
1

I have always put any fancy visibility logic inside the block view hook, eg,

$block['subject']='';
$block['content']='';

switch($delta) {

  case 'foo':

     if ( // visibility condition is true ) {
        // create the block['subject'] and block['content'] here
     }

     return $block;

}

since, if $block['content'] is empty, the block won't be displayed. This might be totally "against the drupal way," but I feel it makes for easier to read code and also takes one less php eval out of the loop.

ADDITION: This appears to get some approval here: Is there a way to set block visibility programmatically without using the PHP Filter module?

5
  • 1
    Yes, a block will show if it has content and if it doesn't it will not. There is no need to set visibility in hook_block_info() for this purpose.
    – rooby
    Commented Apr 22, 2013 at 17:21
  • Thanks for pointing this out! creating visibility condition in the hook_block_view() is way better. makes it posible to just code in your 'code' instead of stuffing ugly it in the $block['modulename_block]['pages'] !
    – FLY
    Commented Apr 23, 2013 at 7:22
  • 1
    Sorry, but I strongly disagree with this. A block, much like a function, should perform the action it's told to perform. It should not be checking external states, ever. Doing so makes re-use much harder. That's not related to Drupal in anyway, it's basic maintainable development. (And in this case, site building)
    – Letharion
    Commented Apr 23, 2013 at 10:36
  • I have gone back and forth here with those exact concerns, @letharion. eg, this logic should be in the theme. but there, eg, in the UI, it's yet another place to loose track of the logic. plus, if it's a choice between setting 'visibility' and 'pages' in $block as posted in the original question, I find having the code "right out there" a slightly better evil.
    – Jimajamma
    Commented Apr 23, 2013 at 14:20
  • shrug, yeah, if we're comparing with PHP filter this solution is absolutely brilliant :P Do you wanna edit the question and perhaps make a note of the potential drawback?
    – Letharion
    Commented Apr 23, 2013 at 14:28
1

In the end I created the block using code: Here's how I've done it:

1) Create a new module or copy an existing one and rename it.

2) Create a block using the hook_block_info() hook. For example:

/**
 * Implements hook_block_info().
 */
function mymodule_block_info(){

  $blocks['mymodule_block_name'] = array(
    'info' => t('Block description'), //The name that will appear in the block list.
    // if you cache blocks on your page and you use the query string for visibility
    // the page doesn't change so you need to set it to DRUPAL_NO_CACHE
    'cache' => DRUPAL_NO_CACHE,
    'region' => 'sidebar_first', // assign block region
    'status' => 1, // enable the block
  );

  return $blocks;
}

3) Create the content of the block using hook_block_view():

/**
 * Implements hook_block_view
 */
function vacancies_block_view($delta = '') {
  // declare empty block
  $block['subject'] = '';
  $block['content'] = ''; 

  // switch block name
  switch ($delta) {

    case 'mymodule_block_name':
      if( TRUE /* put visibility condition here */ ) {

        $block['subject'] = 'Block title';
        $block['content'] = 'Hello world!';

     }
    break;
  }

  return $block; // dont forget to the return the $block!
}

4) upload your code, enable the module, clear cache and check the result.

As suggested by Jimajamma you can hide your block by setting the block subject and content to '' Makes it nicer to put in your condition in php code then using the php filter module.

1
  • Just be sure to reflect on the comments made by @letharion and me on my answer below. This really should be in theme logic, but, there just sometimes isn't a clean way to put it there where it belongs.
    – Jimajamma
    Commented Apr 23, 2013 at 14:46
0

You could use the Rules block visibility module for this (with no custom coding). Here is a quote from its project page:

The Rules block visibility module allows Rules components to be used to control block visibility. This provides Drupal administrators and developers extreme flexibility in controlling when blocks should be displayed on their websites, in addition to the default visibility options provided by Drupal.

The general idea is that if you can do it with Rules, you can use it to control block visibility, so the possibilities are limitless.

Need to show a block only for users registered more than a month ago?

Perhaps you have a block that must be shown only between 8am-5pm on weekdays?

What about displaying or hiding a block based on current weather conditions?

All of this can be done by using Rules block visibility.

With that, and as per the "if you can do it with Rules, you can use it to control block visibility" above, you've reduced your question to making Rules "check the path of the current page" (so that the block is only shown on pages with a question mark).

For an illustration of how to use this module, refer to my answer to "How to stop a Views block from displaying to admins, such as user/1?". It includes a Rules Component (in Rules export format), which you should replace by this variation of it to make it match your specific question):

{ "rules_block_visibility_popular_courses" : {
    "LABEL" : "Hide block for filtered course view",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "USES VARIABLES" : {
      "module" : { "label" : "Module", "type" : "text" },
      "delta" : { "label" : "Delta", "type" : "text" },
      "result" : { "label" : "Result", "type" : "boolean", "parameter" : false }
    },
    "IF" : [
      { "text_matches" : {
          "text" : [ "site:current-page:path" ],
          "match" : "viewname?",
          "operation" : "starts"
        }
      }
    ],
    "DO" : [ { "data_set" : { "data" : [ "result" ], "value" : "1" } } ],
    "PROVIDES VARIABLES" : [ "result" ]
  }
}

Adapt the value of viewname to fit your needs. And to further enhance the above Rules Component (to make it more generic), just replace the Rules condition in it with something using an appropriate regular expression (ie to check if the current path contains a "?".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.