Mark All Drupal Forum Posts as Read

This Drupal 5 module facilitates the creation of a button that allows your Drupal users to mark all topics on a Drupal forum as read. This is a feature of most dedicated forum software which is missing from Drupal's forum module.


  1. Install the module (both markasread.module and needed for Drupal 5) and enable it in the modules administration page
  2. Add a phptemplate_forum_display function to your theme's template.php with something like:
    function phptemplate_forum_display($forums, $topics, $parents, $tid,      
    $sortby, $forum_per_page)
    global $user;
    $forum_display = theme_forum_display($forums, $topics, $parents,
    $tid, $sortby, $forum_per_page);
    $markbutton = '';
    if ($user->uid && function_exists('markasread_form_helper'))
    $markbutton = markasread_form_helper(
    $tid ? t('Mark all topics read') : t('Mark all forums read'),
    $tid ? $tid : NULL);
    return $forum_display . $markbutton;

To Do

  1. Would it be better to use an "UPDATE ... ON DUPLICATE KEY INSERT" query? I saw vague mention of that syntax being supported by PostgreSQL, and being faster in cases on MySQL?


The logic of the SQL query is from this patch. I assume that patch is GPL, which means this module is GPL as well.

There's another similar module: forum_mark_read. It uses N+1 database read queries and N database write queries, where N is the number of forum topics that need to be marked as read. If anyone knows how well that performs, I'd appreciate a comment -- maybe that number of queries is not an issue? forum_mark_read also uses GET, and I need something that uses POST (see above).

Problems, Feedback

If you encounter any issues, please leave a comment below.


Binary Data markasread.info227 bytes
Binary Data markasread.module2.77 KB


I unfortunately do not have a PostgreSQL drupal setup at the moment to verify this test but I believe this should work...

I modified the REPLACE INTO query to a switch test for db_type and used a slightly different query for PostgreSQL. Adding a join to the history table for the user will ensure that the INSERT will not attempt to insert duplicate rows. At least that's the theory :)

switch($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
$sql = 'REPLACE INTO {history} (uid,nid,timestamp)'
.' SELECT %d, n.nid, %d FROM {node} n'
.($tid ? ' INNER JOIN {term_node} r ON n.nid=r.nid' : '')
.' INNER JOIN {node_comment_statistics} l ON l.nid=n.nid'
.' WHERE (n.created > %d'
.' OR l.last_comment_timestamp > %d)';
$args = array($user->uid, time(), NODE_NEW_LIMIT, NODE_NEW_LIMIT);
case 'pgsql':
$sql = 'INSERT INTO {history} (uid,nid,timestamp)'
.' SELECT %d, n.nid, %d FROM {node} n'
.($tid ? ' INNER JOIN {term_node} r ON n.nid=r.nid' : '')
.' INNER JOIN {node_comment_statistics} l ON l.nid=n.nid'
.' LEFT JOIN {history} h ON n.nid=h.nid AND h.uid = %d'
.' WHERE (n.created > %d'
.' OR l.last_comment_timestamp > %d)'
.' AND h.uid IS NULL';
$args = array($user->uid, time(), $user->uid, NODE_NEW_LIMIT, NODE_NEW_LIMIT);

How does one go about moving the location of the botton. (Say from bottom left to top right.) Also how does one display this in a link rather then botton.

You could replace

return $forum_display . $markbutton;


return $markbutton . $forum_display;

to move the button before the forums list. That, plus some CSS should give you the position you want.

I'm not sure, but I think you can get a link to do a POST using javascript.

Please replace 'All topics in forum marked as read' by t('All topics in forum marked as read') and 'All forum posts have been marked as read' by t('All forum posts have been marked as read') so that non english speakers can translate that phrases.

Thanks for your great work!

Done.  Thanks for the suggestion.

You should add a check if the user is logged in, no reason to show the button to non logged in users

here are some changes to the template.php code

global $user;
if (function_exists('markasread_form_helper') && ($user->uid != 0))

Thanks.  I've added such a check to the example code.

It works very fine, thank you.

Any plans to update this module for Drupal 6?

I plan to attempt to update this module for Drupal 6, for the website and community (see

The module is not quite working as expected. Here is a list of things that I have questions about...

1. When someone uses the 'Mark all forums read', it shows up in the forum as marking all of the forums as read. This is good, but when comments are added to existing topics the forum does not show that there is new content. (it does reflect new topics being added.)
How can I fix this???

2. If I have the same forum topics/comments that have been marked as read in a different view (user_tracker for example), that same content shows up as 'new' in the other view even though it should have been marked as read.

3. Probably similar to 2, but the view filter (Node: Has New Content) still shows content that has been 'marked as read'.
How do I fix this???

Cheers and thanks for the module... :)


Thanks for writing this. It's quite useful for a Drupal 5 site that I manage.

One thing I noticed is that when I click the button while in a forum container, topics are not marked as read.

Otherwise, great module. Thanks for writing it. It adds some badly needed functionality to Drupal. :-)

The best part of this module may be it take into consideration a post method of retrieving data rather than gets method which is considered to be unsecure.

Subscribe to All Posts - Wesley Tanaka