UPDATE 2023-03-27: This page is obsolete, as it refers to a prior version of this blog. However, it may be of historical interest.

When I originally put up my blog one of the major things lacking was support for comments and TrackBacks. After looking at the various alternatives (the writeback plugin, the writebackplus plugin, and so on) I decided to embark on a complete rewrite of the writeback plugin in order to support my particular requirements for a comments system. After much struggle I created an initial version of my feedback plugin for publication and use on my site; since that time I’ve upgraded the plugin and incorporated bug fixes suggested by various people.


I did a pretty much complete rewrite of writeback and the various writeback derivatives, both because they didn’t support particular features of interest to me and also because I didn’t understand exactly why they did certain things the way they did. Here are the key things I wanted, all of which I managed to implement in one form or another:

  • no need to use a special writeblack flavour
  • different formatting for comments vs. TrackBacks
  • correct formatting of basic plain-text comments (in particular, if you enter paragraphs separated by blank lines then the resulting comment should actually display as multiple paragraphs, without requiring you to use HTML tags)
  • comment previewing
  • comment and TrackBack moderation
  • basic spam blacklist checking using Akismet
  • basic security measures against code injection attacks
  • Markdown support (although I’m not using it right now)
  • clean enough code structure to allow easy addition of new features
  • minimal dependence on other plugins


There were a number of other features that I didn’t care about and decided to leave out:

  • Captcha support. I omitted this in favor of a combination of Akismet spam checking plus (optional) moderation; unlike captchas, this protects against TrackBack spam, not just comment spam.
  • HTML tags in comments (even just a subset). I think Markdown is a better approach for those who want links and more complicated formatting.
  • Comment threading (e.g., as implemented in the comments plugin). This just wasn’t that important to me.
  • A writeback compatibility mode (i.e., the ability to use the feedback plugin as a drop-in replacement for the writeback plugin, using legacy writeback templates and variables). The plugin could probably be enhanced to support this, but I’ll leave it to someone else to do this.
  • Correct display of comment and TrackBack counts (e.g., displaying “1 comment” vs. ’2 comments"). I left this as a future task.
  • A generalized API for extending features through feedback-specific plugins, e.g., as implemented by Doug Alcorn for writeback. While an interesting concept, I felt this was a bit heavyweight for what I wanted to do.

There were also several features that I initially implemented and then later pulled out in the interest of simplicity:

  • Ability to display comments and TrackBacks on index and archive pages. (Right now the plugin displays comments and TrackBacks only on individual story pages.) I’ve seen some Blosxom-based blogs that do this, but it wasn’t something I was interested in. (For anyone who wants to do this, it’s a trivial patch.)
  • Support for “comments_head” and “comments_foot” templates to provide additional content to be displayed before all comments and after all comments (with analogous “trackbacks_head” and “trackbacks_foot” templates for TrackBacks). In the end I found I could use variable interpolation (as supported by the interpolate_fancy plugin) in the story and/or foot templates to achieve the look I wanted.
  • Support for a separate “preview template” used for previewed comments; in the end I just reused the comment template for this.
  • Support for HTML email for moderation and notification messages. I decided that plain text email worked fine and was arguably better from a security point of view.


Finally, here some implementation details that might be of interest to people using or (especially) writing writeback-like plugins:

  • The feedback plug-in contains all the default templates needed that are specific to the plug-in; you should only have to modify your existing story and foot templates to reference the plugin variables (as described in the documentation at the bottom of the plugin).
  • I used the same basic file structure to store comments and TrackBacks as is used by writeback and friends. (In fact, I think you may be able to use existing writeback files with this plugin, but I haven’t tested this.)
  • I moved processing of submitted comments from the start subroutine into the story subroutine. This seemed to simplify the implementation, especially when it came to deciding whether or not comments or TrackBacks should be closed after a certain time. (To do this properly you need the modification date/time of the story, which you don’t have until the date subroutine runs, right before the story subroutine.)
  • Comment previewing was pretty straightforward to implement: It’s basically a matter of keying off the particular submit button clicked, formatting a special “preview” comment separate from the main comments, and then pre-filling the comment form fields with the previewed field values.
  • Moderation was also pretty straightforward (after a couple of false starts): Write the moderated comment or TrackBack not to the main feedback file for the story, but to a separate file whose name contains a randomly-generated 8-character alphanumeric string. To support approval or rejection of the comment or TrackBack, create moderate=approve and moderate=reject URLs referencing that string as a query parameter (e.g., feedback=mi3g9qcl4) and send those URLs to the moderator as part of an email message notifying them of the comment/TrackBack. When the moderator clicks on the appropriate URL and the plugin processes the GET request, it will either append the temporary file to the main feedback file (if the request was approved) or just delete it (if the request was rejected). The use of a random string minimizes the possibility of unauthorized persons trying to approve their own requests. (This doesn’t protect against eavesdropping attacks, of course; doing that would require some use of cryptography.)
  • The plugin seems to support non-ASCII posts (e.g., in Japanese, etc. ), except in the notification/moderation email messages. I suspect this is just be an artifact of the particular version of Perl I’m using; I certainly didn’t do any work to support anything but 7-bit ASCII, and it may be that some things are still broken even in my case.

Anyway, I hope this may be of interest to some people. As always, please feel free to re-use the code or ideas as you wish. See the plugin itself for the full documentation on how to configure it. If you encounter problems with the plugin (or if you just use it and like it) please send me email.

UPDATE: Added mention of Akismet support. Thanks go to Kevin Scaldeferri for the Akismet support (adapted from his version of writebackplus) and to Keith Carangelo, Gustaf Erikson, Matthijs Kooijman, and Michael Lamertz for various bug fixes and related suggestions for improvement.