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
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.
I was also looking at pulling data from node_counter, with this SQL:
SELECT * FROM node_counter n where daycount > 0 order by daycountother types of popular
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
thank you! I'm surprised there isn't a block for this already
There is
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?
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
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
<?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
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
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
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
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
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!
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!
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?
Hi,
Is there a drupal 5 version of this snippet?
Thanks in advance!
greetings,
Martijn
+1 for drupal 5 version of
+1 for drupal 5 version of this :)
In 5.x
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
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
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.