"New!" markers in Movable Type

Over on Pepys’ Diary it’s not unusual for each day’s entry to have 20-30 comments posted to it. Because these discussions are currently all displayed by Movable Type there are none of those interface clues common to forum systems that indicate what a user has yet to read, or which entries (or topics, as they’d be on a forum) have the latest comments.

The latter problem was solved by the Recent Annotations page, which lists the most-recently-commented-on diary entries. But it was still tough to keep up with what one hadn’t read yet. So I wrote some PHP that can be used to generate the “new” markers you now see on pages like this. These indicate which annotations have appeared since a user’s previous visit. (If this is your first time there, or the first time since I implemented the code, everything will be marked as new right now.) The same could be done for weblog entries, but it’s not needed so much on Pepys, given how regular the enries are.

So, if you want to do this, and you’re using PHP and Movable Type, here’s how.

  1. Save this file to your webserver as something like “newitem.php”.
  2. Edit the $domain and $weblogpath variables to reflect your set up. $weblogpath is the path under which the cookies will function. If there is, or will be, more than one weblog at this $domain, you’ll need to make $weblogpath specific to the weblog you’re using this code on.
  3. Edit the $newtext and $oldtext strings. These are what will be displayed if the entry or comment is new or old. One or both can be left empty and they can contain HTML (escape double quotes with a backslash: \"). Before you use the code in public you could wrap the HTML in comment tags (eg, <!-- NEW -->) so you can check it’s working by looking at the page source.
  4. Include the file in each page of your weblog before the point at which any text or HTML is output. If you’re already using PHP you probably know that a file is included by doing this:
    include ("/path/to/your/site/newitem.php");
  5. In your Movable Type templates you’ll have to call the newItemMarker() function wherever you want the marker to appear. It should be passed a time of the format “YYY-MM-DD hh:mm:ss”. If you’re putting a marker at the start of each entry you might do something like this:
    <h3><?php newItemMarker("<$MTEntryDate format="%Y-%m-%d %H:%M:%S" encode_php="qq"$>"); ?><$MTEntryTitle$></h3>
    <$MTEntryBody$>
    You’ll then get a marker appearing before the entry title. Do exactly the same if you want to put a marker next to comments, but use MTCommentDate instead of MTEntryDate.
  6. Rebuild your site…

The comments in the code should explain what it does. Three times are stored in cookies: the time the last page was viewed; the time the current session started; and the time of the last page view in the previous session. Sessions are set to 90 minutes long by default, but this can be changed by editing the $sessiontime variable.

Every time a page is viewed, the first cookie is set with the current time. The other cookies are set if sessions are starting or ending. When the newItemMarker() function is called it compares the time passed to it (that of an entry or comment) and decides if the item is new for this user. The correct marker is then displayed.

Of course, things go wrong if the user is using more than one computer or browser, but otherwise it seems to work. I don’t claim it’s perfect (figuring out what cookies to set with which times made my head hurt), but it seems to work for me. Let me know if you have problems or thoughts for improvement.