5

I want to place put a block in a view page. Let's say the news page, whose path is http://www.example.com/news.

The view uses pager to list the content.

enter image description here

I want a block to show up only in the very first page of the news page (http://www.example.com/news), excluding from paginated pages, such as news?page=1, news?page=2.

I set the visibility to only list in news, but the block still shows up in news?page=1, news?page=2.

How can I show a block in a view page, excluding its paginated pages?

1
  • Php use to be a bad idea if it had to be stored in database, in terms of maintenance, performance, security, ... A good solution could be that module: drupal.org/project/block_views Commented Feb 16, 2014 at 23:05

4 Answers 4

4

You can also achieve the same in using following snippet, in the blocks visibility settings by turning PHP code on,

<?php
  $url = request_uri();
  $pos = strpos($url, "page");
  if ($pos === false && arg(0) =='news') {
    return TRUE;
   }
 ?>
1
  • Thanks, this is certainly an option. But prefer not to use PHP filter module in my case for security measure.
    – gilzero
    Commented Oct 29, 2012 at 10:01
1

I would check out the Context (http://drupal.org/project/context) module. Add a condition "Path" and enter in news just like you would on the normal blocks page.

Then, add ~news?page=* which will exclude (the ~ indicates exclude) any pages with the "page" argument.

There might be a better way, but that's the best thing I can think of.

3
  • Have you tried that. I just tested, doesn't work. Context condition: [Path] > news and ~news?page=* , Reactions: Blocks > Recent comments in sidebar. Clear cache, refresh. Recent comments block still shows up in news?page=1 (2,3,4 .....) Won't work, did not respect the path condistion, any idea?
    – gilzero
    Commented Oct 29, 2012 at 11:16
  • I confirm that '~news?page=*' won't work.
    – gilzero
    Commented Nov 1, 2012 at 17:24
  • What I did was to add a Condition in Context call "Query String" with the statment ~*page=*. It worked perfectly.
    – user42389
    Commented Jan 21, 2015 at 15:06
0

Instead of using PHP code in your block visibility settings (which gets stored in your database ...), to not show the block on paginated pages (as in your question), you can also use the Rules block visibility module for this. 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 path that matches "news" and does NOT start with "news?page=").

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_show_block_on_page_with_no_url_parms" : {
    "LABEL" : "Show block on page with no url parms",
    "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" : [
      { "data_is" : { "data" : [ "site:current-page:url" ], "value" : "news" } },
      { "NOT text_matches" : {
          "text" : [ "site:current-page:url" ],
          "match" : "news?page=",
          "operation" : "starts"
        }
      }
    ],
    "DO" : [ { "data_set" : { "data" : [ "result" ], "value" : "1" } } ],
    "PROVIDES VARIABLES" : [ "result" ]
  }
}
0

I am submitting another answer to fill in some info gaps that I ran into while trying to implement the solution by @KraigH and the updated solution by @gilzero (figures are in the image below, I cannot yet post more than two images).

  1. Make sure you do not have your blocks enabled on the block page, those settings will conflict with the solution, @see Figure 1.

  2. Set up a context and set your path to your view (blog in my case), @see Figure 2.

  3. Under your actions set all the blocks for that region, including the main content region if you need to place your blocks above or between existing blocks in that section. Adding them will allow you to rearrange their order, even if they are already being displayed, @see Figure 3.

    implementation images

  4. Once this is set up, you can use the code to alter them in a custom module. Make sure that your $context->name matches your name you set in the context module. Also I adjusted the $paged code to account for the cleanpager module.

 

/**
 * Implements hook_context_load_alter().
 */
function MYMODULE_context_load_alter (&$context) {

  // Whether current page is under paginated pages. e.g 'news?page=1'
  $paged = (isset ($_GET['page']) && preg_match('|^[0-9]+$|', $_GET['page']) && $_GET['page'] != '0');

  // If yes and context is the specific one:
  if ($context->name === 'exclude-blocks-from-pager' && $paged) {

    // Remove particular block placement:
    if (isset ($context->reactions['block']) && isset ($context->reactions['block']['blocks'])) {
        if (isset($context->reactions['block']['blocks']['views-blog-block_2'])) {
            unset ($context->reactions['block']['blocks']['views-blog-block_2']);
        }
        if (isset ($context->reactions['block']['blocks']['views-blog-block_3'])) {
            unset ($context->reactions['block']['blocks']['views-blog-block_3']);
        }
    }
  }
}

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.