2

I have a view block which shows lists of content type "news" which displays in a sidebar showing only the node title for users to peruse.

There are about 150 such "news" nodes and so I use pagitation.

These "news" nodes are completely linear. You always want to read them in order. So if you read node/20, you must read node/21 next, then node/22 etc.

I would like the view block in the sidebar to display the titles of 2 nodes BEFORE and AFTER the current node. So, if I went to node/20, I would like the view block to display:

  • Title of node/18
  • Title of node/19
  • Title of node/20 (current node being viewed)
  • Title of node/21
  • Title of node/22

I was hoping for some pointers as to how I might achieve this. All things that I've tried thus far have proved futile.

Thanks.

1

In your View, under Block Display, go to:

Advanced-> Contextual filters (Add)->Content: NID

In the "When the filter value is NOT available" option select:

Provide default value-> PHP Code

and add the following code:

if (arg(0) == 'node' && is_numeric(arg(1))) {
  $nodeid = arg(1);
  $result = strval($nodeid-2) . "+" . strval($nodeid-1) . "+" . strval($nodeid) . "+" . strval($nodeid+1) . "+" . strval($nodeid+2);
  return $result;
}

Last but not least, under "More", select the option: "Allow multiple values"

  • You can get the node id from URL "Provide default value-> Content ID from URL" and use it as $handler->argument in validation code under: "When the filter value IS available or a default is provided", so it can be made without the IF statement. My +1 for an example of using PHP code in contextual filter. – Jack-PL Jun 1 '13 at 23:38
1

In relation to your comment:

Limit the output of this view to a particular content type

$nid = $handler->argument;  // the node id from url
$nodes = array();           // an array for node id's
$type = "news";             // content type (mashine name)

// get two previous node id's and the present one
$result = db_query("SELECT nid FROM {node} 
                    WHERE nid <= :nid 
                    AND status = :status 
                    AND type = :type 
                    ORDER BY nid DESC 
                    Limit 3", 
                    array(  ":nid" => $nid, 
                            ":status" => 1, 
                            ":type" => $type
                            )
                    );
foreach ($result as $row){
    $nodes[] = $row->nid;
}

// get next two node id's
$result = db_query("SELECT nid FROM {node} 
                    WHERE nid > :nid 
                    AND status = :status  
                    AND type = :type 
                    ORDER BY nid ASC 
                    Limit 2", 
                    array(  ":nid" => $nid, 
                            ":status" => 1, 
                            ":type" => $type
                            )
                    );
foreach ($result as $row){
    $nodes[] = $row->nid;
}

// compose and return the filter argument
$handler->argument = implode('+',$nodes);
return $argument;

"Allow multiple values" has to be selected

This solution should suit your needs if your are going to show this block only on particular content type ("news" in this case).

  • Thank you for your input here. Having thought about this some more, I think that I really DO need to think about the deleted nodes. There might well be many of those. Not being a programmer, I'd really appreciate your input on how I might limit the output of this view to a particular content type. Would you just do this in the Views UI, or would you add code to the above? If it's adding code, what might I need to add please? Thanks again. – njwrigley Jun 2 '13 at 15:21
  • I edited my answer and wrote the code which limit the output to a particular content type. I think, in this case it should be done with the php code. Just replace the previous code for the new one. – Jack-PL Jun 2 '13 at 20:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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