Most Popular nodes.

spatz4000 - February 2, 2006 - 14:30

I would like to have block that shows the titles of the site's most popular stories. I thought that I could do a SQL statement that would gather the most clicked on links, but some basic testing shows me that isn't working. I was doing this:

SELECT * FROM clicks c I then clicked on a link a few times, but the day_clicks,week_clicks, and total_clicks did not increment.

You can get this info from

Ian Ward - February 2, 2006 - 14:41

You can get this info from the core statistics module, which you'd need to enable, and use something like $stats = statistics_get($node->nid); to load the stats object of a given node, then pull out totalcount from the object for each node.

Ian

Thanks for the info.

spatz4000 - February 2, 2006 - 14:44

I was also looking at pulling data from node_counter, with this SQL:

SELECT * FROM node_counter n where daycount > 0 order by daycount

other types of popular

Ian Ward - February 2, 2006 - 16:01

BTW, here's a link to a snippet on doing a popular node block where popularity is defined by the number of comments on a post:

http://drupal.org/node/29722

Ian

thank you

kae - February 2, 2006 - 14:45

thank you! I'm surprised there isn't a block for this already

There is

Heine - February 2, 2006 - 14:52

Enable statistics. Enable Count content views in administer » settings » statistics. Then go to administer » blocks and enable Popular content.
--
Tips for posting to the forums.
When your problem is solved, please post a follow-up to the thread you started.

How about EXCLUDING nodes from Popular Content?

jraper@groups.d... - May 17, 2006 - 04:21

I see how to enable and use Popular Content - I have that working just fine and it works great. But what about the opposite case - that being utilizing Popular Content for some part of a site while EXCLUDING other nodes from Popular Content. I.e., is there any way to prevent certain nodes (or paths) from being considered by the Popular Content function?

The only way I could figure

nikkiana - June 6, 2006 - 16:23

The only way I could figure out how to do it was to go in and edit the SQL statement that's in the statistics_title_list function... It's an awfully dirty way to get the desired results though.

nikkiana
everytomorrow.org - blogsNH

Here's a snippet that might help

markj - April 26, 2006 - 16:20

<?php

 
/*
   Code snippet to list most popular nodes, specifically, the ones with the highest 'totalcount'
   value in the 'node_access' table. Formatted here as a bulleted list using theme_item_list for
   Drupal 4.6; same function in 4.7 allows definition of an ordered list.
  
   If you want to limit the query to specific node types, include n.type in your SELECT list
   and use n.type = 'blog' or n.type = 'flexinode-2' in your WHERE clause.
  */

 
$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)
    ORDER BY nc.totalcount
    DESC "
, 0, 10);
  while (
$node = db_fetch_object($result)) {
       
$output[] = "<a href=\"?q=node/$node->nid\">" . $node->title . "</a> ($node->totalcount views)";
  }
 
// Works in 4.7: return theme_item_list($items = $output, $title = 'NULL', $type = 'ol');
 
return theme_item_list($output);
?>

re: Here's a snippet that might help

srlinuxx - May 9, 2006 - 19:22

How might one add the date of publication to the output perhaps before or after the view count, maybe enclosed in dashes - ?

thanks!

--You talk the talk, but do you waddle the waddle?

Here's a template, you can format the date the way you want

markj - May 15, 2006 - 02:09

Nodes don't have a date of publication, but they do have a date of creation.

In the example below, the only changes from the original are that I've added 1) "n.created" to my SELECT list and 2) "date('F j, Y, g:i a', $node->created)" to the output. See example 4 at http://ca.php.net/manual/en/function.date.php for more format choices.

<?php
$result
= db_query_range("SELECT n.title, n.nid, n.created, nc.nid, nc.totalcount
    FROM node n, node_counter nc
    WHERE n.status = 1 and (n.nid = nc.nid)
    ORDER BY nc.totalcount
    DESC "
, 0, 10);
  while (
$node = db_fetch_object($result)) {
   
$node_type = $node->Type;
       
$output[] = "<a href=\"?q=node/$node->nid\">" . $node->title . "</a> -- Created " . date('F j, Y, g:i a', $node->created) . " ($node->totalcount views)";
  }
?>

Snippet security

Heine - May 15, 2006 - 05:36

Hello Markj,

Thanks for the snippet. I hope you won't mind some tips.

As it is right now, it suffers from two security related problems:
1 - The query bypasses node access restriction leaking title information (which may be your intent)
2 - It allows cross site scripting attacks, because $node->title is printed without checking output.

Writing secure code and links therein contain more information on the subject.

Because you're making links you can use the function l (el) to solve 2. This function does check output and gives nice urls as a bonus.

Some additional tips: use format_date to format dates according to site administrator preferences and user timezone. Of course it's also possible to use a custom format.

Use theme('item_list', $output) instead of theme_item_list($output). The first format will give the exact same results but allows overriding by the theme, whereas theme_item_list() can't be overridden.

In addition: it should be $node->type, not $node->Type; PHP variables are case sensitive.
--
When your problem is solved, please post a follow-up to the thread you started.

Thank you

markj - May 17, 2006 - 04:40

Heine, thanks for pointing out the security and other problems. I'm just beginning programming in drupal and tend to forget to look in drupaldocs to see if there is a secure or better function. Here's the snippet incorporating your suggestions:

<?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
    ORDER BY nc.totalcount
    DESC "
, 0, 10);
  while (
$node = db_fetch_object($result)) {
   
$output[] =  l($node->title, "node/$node->nid") . " ($node->totalcount views) -- Created " . format_date($node->created, 'custom', 'F j, Y, g:i a');
  }

  return
theme('item_list', $output)
?>

In this case I don't mind if all users can see the title; if they clicked on the node's link but didn't have view permissions to that node type, they would get a not authorized error, right? Or is there something else about node titles and security I'm missing?

re: most popular

srlinuxx - June 9, 2006 - 22:58

you forgot n.created in the line:
$result = db_query_range("SELECT n.title, n.nid, nc.nid, nc.totalcount

otherwise, you don't get the correct date output.

--You talk the talk, but do you waddle the waddle?

This ruled!

neoliminal - September 26, 2006 - 17:04

I was so happy to find this. I needed it "right now" and there it was, ready to plug in as a block. Perfecto!! Many many thanks!

Nice snippet!

gopher - October 5, 2006 - 17:27

Yes, this is a great snippet! I wonder if there's a way to restrict the results by time as well? So only the 'most recent' nodes are counted.

Drupal 5 version?

Summit - January 10, 2008 - 12:57

Hi,

Is there a drupal 5 version of this snippet?
Thanks in advance!
greetings,
Martijn

+1 for drupal 5 version of

omnyx - March 4, 2008 - 04:31

+1 for drupal 5 version of this :)

In 5.x

spatz4000 - March 4, 2008 - 15:55

This is how I did the most Popular in Drupal 5:
You need to have views installed.

   $module = 'views';
    $delta = 'popular_recent';

    $block = (object) module_invoke($module, 'block', 'view', $delta);
    $block->module = $module;
    $block->delta = $delta;

    $mviewed = theme('block', $block);
    print $mviewed;

hm...but that does exactly

omnyx - March 4, 2008 - 16:16

hm...but that does exactly the same as the popular_recent block, right?
I think the snippet is meant to show only certain content_types.

Most popular blogs

JimmyMoonJam - February 25, 2009 - 23:46

Same snippet as above for blogs in 6.x please? I don't want to install Views module only for this block. I just want to list most popular blog pages. I've seen a lot of people asking this here.

 
 

Drupal is a registered trademark of Dries Buytaert.