Personalizing “New” Labels

How to let the site visitor know which documents he hasn't seen.
Bringing the User Into the Picture

The above technique is a good start, but it still ignores the user's perspective. That is, the links are expired on an absolute time scale. But a user who visits the site less than once per week will see too few “new” labels, while someone who visits it more often than once per week will see too many “new” labels.

How can we take care of that situation? One way is to keep track of when the user last visited our site, and make the comparison to that time stamp rather than to the file's creation or modification date. How can we know when the user last visited our site? Since HTTP, the protocol used to transport most Web documents, is “stateless”, each transaction takes place in a vacuum. When a web browser makes a request to a server, the request is not connected to any previous or following request. No information about previous requests is passed along, and nothing we do in our request is saved for later ones.

The best and easiest way is to use HTTP cookies, which nearly every browser supports. Cookies are variables set by the server and stored on the client's computer. Cookies allow us to track state across transactions by storing information on the user's computer. When the server next encounters the user, it can compare the time stamp on the cookie with the time stamp on the file.

Thus, we can rewrite the above program so that it auto-expires the labels based on when the user last visited the site. Each time the user visits our site, we set a cookie. The cookie's expiration date is set to be one week in the future, meaning that if the cookie exists, this user visited our site within the last week. Our labeling program (Listing 2, then has a simple way to determine whether it should print “new” next to a link—the label should be printed only if the cookie does not exist.

Listing 2. with Cookie Check

Because we are using, which includes all necessary functionality for writing CGI programs, we can check whether the cookie exists in this way:

my $visited_recently = $query->cookie('RecentVisitor');

We can then print the label with the following code:

if (!$visited_recently)
        print "<font color=\"red\">(New!)</font>\n";

Setting the Cookie

That about does it for reading the cookie. But how do we write the cookie? This is a stickier problem, one which has a number of potential solutions. The cookie specification requires that an expiration date be written with a full UNIX-style time and date stamp, as in

Thu Apr  8 02:25:30 IDT 1999

We cannot simply create and send a cookie with an expiration of “one week in the future”. We also have to figure out a way to set the cookie from within our HTML file—unless we want to use a CGI program to send the text, which would defeat the purpose of using SSIs to begin with.

One solution, although admittedly not the most elegant or efficient one, is to take advantage of the META tag supported by standard HTML. META tags have a number of uses, among them the ability to send data that would otherwise be sent in an HTTP header.

Since HTTP cookies are sent as part of the header in the browser's HTTP request, it's possible to set the “RecentVisitor” with the following HTML at the top of our page, within the <Head> section:

CONTENT="RecentVisitor=1;expires=Thu Apr
15 02:19:17 1999; path=/">

This tells the browser it should pretend a Set-Cookie HTTP header was sent from the server, and the content attribute should be handled as if it were the header's value. That is, the above META tag sets the RecentVisitor cookie to 1 and allows the cookie to be anywhere in my domain. The cookie is set to expire on April 15, 1999.

Creating this META tag is a bit difficult, since the date depends on when the user loads the page. If the user loads the page on April 8, the cookie should be set to expire on April 15. If the user loads the page on April 10, the cookie should expire on April 17. We need to modify the output according to when the user visits.

Listing 3.

The fact that the cookie's expiration date must change with time means we need to insert a program somewhere. The easiest way to do this is with another program invoked via SSI, which will create the META tag for us. Such a program,, is shown in Listing 3. With that installed and in place, we can say

<!-#include virtual="/cgi-bin/" ->

Our program,, sets the cookie's value by creating a META tag based on when the user accesses it. With this in place, each visit to our site will produce a cookie that disappears (or “crumbles”, if you prefer) within one week. Our SSI checks to see whether that cookie was sent, and if it was, prints an appropriate “new” label.