Nov 03 2006

Excluding Nodes from Drupal's Popular Content Blocks

Categories:


Upgrading the Views Popular Content Blocks

I installed the views module popular content blocks (the all-time popular content block, and the recent popular content block), but noticed that they also listed the front page as the most popular, something that I felt was unecessary. This article discusses code snippets that will let you exclude certain node ID's (and paths) from inclusion.

In case you are wondering why you don't see the "popular content" views in your views settings, you need to do the following to get them to show:

  • enable the statistics module
  • browse to admin -> settings -> statistics -> and enable "count content views."
  • go to administer -> blocks -> and enable the "popular content" blocks.

You can adjust how many content items show by editing the popular content view under admin -> views. However, short of hacking the statistics module, I did not find a way to modify the view to exclude certain nodes. In lieu of this here is a PHP snippet that you can copy and paste into a new block that will let you exclude particular node ID's:

Today's Popular Content

<?php
  $result
= db_query_range("SELECT n.title, n.nid, nc.nid, nc.daycount
    FROM node n, node_counter nc
    WHERE n.status = 1 and n.nid = nc.nid and n.nid != 3
    ORDER BY nc.daycount
    DESC "
, 0, 5);
  while (
$node = db_fetch_object($result)) {
   
$output[] =  l($node->title, "node/$node->nid") . " ($node->daycount)";
  }
  print
theme('item_list', $output);
  print
'<p style="text-align: right; padding-right: 1em"><a href="/popular/latest">[ View All ]</a></p>';
?>

Code Explained

The node_counter table keeps track of page accesses; both daily accesses (in daycount) and alltime accesses (in alltime). The above snippet references daycount to produce a block of "today's popular content," while the snippet below references alltime to produce a block of "all-time popular content." I also specify nodes that I don't want included in the WHERE clause. In this case, my front page node ID is 3, so I exclude it with the line

WHERE ... and n.nid != 3

You could also cross-reference the url alias table to exclude nodes by path name.

All-Time Popular Content

<?php
  $result
= db_query_range("SELECT n.title, n.nid, nc.nid, nc.totalcount
    FROM node n, node_counter nc
    WHERE n.status = 1 and n.nid = nc.nid and n.nid != 3
    ORDER BY nc.totalcount
    DESC "
, 0, 5);
  while (
$node = db_fetch_object($result)) {
   
$output[] =  l($node->title, "node/$node->nid") . " ($node->totalcount)";
  }
  print
theme('item_list', $output);
  print
'<p style="text-align: right; padding-right: 1em"><a href="/popular/alltime">[ View All ]</a></p>';
?>

I hope this proves useful to someone. Please post any questions/ comments below.

References: There is a further discussion of popular content blocks in this Drupal thread and a visual popular content block, similar to the one used on c|Net, discussed in this thread.

Average: 4.3 (3 votes)

Select your preferred way to display the comments and click "Save settings" to activate your changes.

very useful!

Very useful! I was looking to do exactly this -- you've saved me a lot of time! many thanks!

Very cool - it's always nice

Very cool - it's always nice to hear that my articles are useful to someone! Thanks for the mention!

Smiling

Yo

Is it posible to exclude more nodes? With this I can exclude just one node or more?

Excluding nodes

You can exclude as many as you need to:

WHERE n.status = 1 ... and n.nid != 3 and n.nid != 4, etc.

Thank you!

Thank you very much!!!

  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • Textual smileys will be replaced with graphical ones.

More information about formatting options

Captcha
This question is used to make sure you are a human visitor and to prevent spam submissions.
Copy the characters (respecting upper/lower case) from the image.