I’ve implemented a simple comment system in which

  • there are no user accounts
  • has a preview function
  • once a comment is submitted you cannot edit it anymore
  • all comments are moderated
  • a small set of BB tags are allowed
  • implemented as one PHP file
  • the PHP script has some html in it
  • needs a writeable directory in your document root

You need this file: comment.php.

The first few lines allow for some customization:

$NB_TIME = "%Y-%m-%d %T %Z"; # strftime function
$NB_COM_BASE="/home/miekg/miek.nl/blog/comments";
$NB_COM = 1;	# 0 -> disable comments
$NB_COM_CLOSE = 2592000; # number of seconds after which comments are closed
$NB_COM_MAX_SIZE = 2000; # max number of chars in a comment

which have the following meaning:

  1. NB_TIME: how to format the time and date of the comment
  2. NB_COM_BASE: where to put the comment files
  3. NB_COM: emergency comment disable, when 0 all commenting is disabled
  4. NB_COM_CLOSE: number of seconds when commenting on an article is disabled
  5. NB_COM_MAX_SIZE: maximum number of character per comment.

In NB_COM_BASE all comments are put, each article gets a directory named after its $NB_EntryID. In that directory, two sub dirs are made ok and new. All comments are first put in the new directory, where they wait for moderation. See below for the moderation script.

Further more you need to tweak apache to allow PHP code in .html files or make nb create .php files.

In all files you will need to following code:

<?php
require "/home/miekg/miek.nl/comment.php";
?>

Of course you need to use a different path for your situation.

comment string

In articles you will need something like comments: (5) with comment.php the following is needed (remember the shell is touching this code too, so you’ll need to escape the PHP stuff):

<?php
echo commentstr($NB_EntryID, ${ARCHIVES_PATH}$NB_EntryPermalink);
\$comments =  gather($NB_EntryID);
echo "(" . count(\$comments) . ")";
?>

Or whatever you want to put there. The gather() function will retrieve the current comments of this article. It will also create a link to the permalink of the article as I decided that new comments are to be added there.

adding comments In my permalink template I have the following code: Note: 1) the shell is touching is and 2) my templates are written in m4, where I’ve made ‘[’ and ‘]’ mean something, hence the double ‘[[’ and ‘]]’):

<?php
show(\$comments);
if (\$_POST[['preview']] == "Preview Comment") {
    preview();
}
if (\$_POST[['submit']] == "Submit Comment") {
    submit();
}
form("$NB_EntryID");
?>

Well this kinda speaks for itself. A user can preview comments when pressing ‘Preview’ in the form and for submitting submit is pressed.

The form() function displays the commenting form.

moderation script After a comment has been left in the new/ directory it needs to be moved to the ok/ dir. I’ve written nbadmin for this purpose. A typical run looks like this:

> Article: e2009-01-12T19_34_47.txt
 >> Comment found: 1232783070_uvTSOy
<a href="http://miek.nl">Miek Gieben</a>
Test 123
(A)approve (D)discard (N)skip [A]: A
new/1232783070_uvTSOy ok/1232783070_uvTSOy

And with that the comment is okayed.

cron job

Of course you want to be notified of new comments, this is implemented as a cronjob which checks if there are any files in a new/ directory.

The quick and dirty script:

#!/bin/sh
# send email for the comments that are found in my website
COM_BASE="/home/miekg/miek.nl/blog/comments"
BODY=""

for art in $COM_BASE/*.txt; do
for com in $art/new/*; do
    if [ $com = $art/new/* ]; then continue; fi
    BODY="$BODY\n o $com"
done
done

if [ ! -z "$BODY" ]; then
echo "New comments found for miek.nl"
echo ${BODY}
fi

And my cronjob:

% crontab -l
MAILTO=miek@atoom.net
# check if there are new comments
10 8-22/2 * * * /home/miekg/bin/nbnotify