Home Articles FAQs XREF Games Software Instant Books BBS About FOLDOC RFCs Feedback Sitemap
irt.Org

Related items

CGI Security : Better Safe than Sorry

Creating a Page Counter In Perl

Speed Thrills : CGI Please ... and Fast!

CGI Programming Made (Relatively) Easy Using Libraries

Server-Side Includes and its Extensions

Random and Recursive Crypting using Salt on Unix and Win32

Deleting Files in Perl

Creating a mailing list using Perl

Reading and Writing to Files on the Server

Server Side Includes and CGI Security

Timestamping an HTML Document

You are here: irt.org | Articles | CGI & Perl | Timestamping an HTML Document [ previous next ]

Published on: Saturday 14th November 1998 By: Pankaj Kamthan

Introduction

Timestamping an HTML document that one has created conforms to a "good" style of HTML markup [Ref. 1]. It gives the viewer a sense as to how old the document is. Perhaps, more importantly, this is of relevance to a returning user who may first wish to know if the document has been modified since he/she visited it the last time before browsing through. Many HTML editors  in current use (such as Emacs with the html-helper-mode or Microsoft FrontPage 98) have a built-in capability of including-in the date of last modification automatically when one saves the document. In this article, we show two ways of how it can be done without the use of special-purpose HTML editors.

Server-Side Solution

Using Server-Side Includes (SSI's)

This method uses SSIs. For this, an appropriate WWW server directive should be enabled. (For example, the Apache WWW server has such a directive.) Please contact your WWW server administrator, if you are not familiar with it.

Create a file called lastmodified.shtml with the following line:

Last Modified: <!--#echo var="LAST_MODIFIED" -->

Include the line

<!--#include virtual="lastmodified.shtml"-->

at the end of your HTML document in which you wish to include the last modification date and save it with extension .shtml. You can also introduce different colours and fonts in your lastmodified.shtml file to make the output more attractive.

Using the flastmod directive, you can also inserts the last modification date and time of other documents. (The difference between the SSI environment variable LAST_MODIFIED and this command is that, flastmod allows you to choose any file, while LAST_MODIFIED displays the information for the current file.) For example:

<!--#flastmod virtual="/path_to/foo.html"-->

This can be useful if you have an index or table of contents page which not only lists what documents are available, but also when were they last modified, as the next example illustrates:

<HTML>
<HEAD>
<TITLE>Table of Contents</TITLE>
</HEAD>
<H1>Table of Contents</H1>
We have the following information for you:
<UL>
  <LI>Document 1 (Last Modified : <PRE><!--#flastmod virtual="/path_to/1.html"--></PRE>)
  <LI>Document 2 (Last Modified : <PRE><!--#flastmod virtual="/path_to/2.html"--></PRE>)
.
.
.
</UL>
.
.
.
<PRE>
<!--#echo var="LAST_MODIFIED"-->
</PRE>
</BODY>
</HTML>

Using CGI

In dynamically generated HTML documents using CGI in Perl 5, you can insert a time stamp by including:

$last_modified = localtime (time);
print "Last Modified : $last_modified\n";

in your CGI script.

Limitations

Use of SSI's is not always recommended as it puts a load on the server each time a file of the type *.shtml is accessed. (SSI's, of course, have many other uses - as an alternate or in conjunction to CGI scripts.) The same argument holds for dynamically generated HTML documents using CGI, particularly if they are generating a page (such as the home page for a site) that is frequently accessed. It is not much of a hindrance in this case, since the file size (of lastmodified.shtml) is small.

Client-Side Solution

Using JavaScript

To use this method, the browser should be JavaScript-compatible (such as Netscape Communicator 2.0+ or Microsoft Internet Explorer 3.0+). Including the following segment of code in your HTML document does the work:

Script 1.

<SCRIPT language="JavaScript"><!--
document.write(document.lastModified);
//--></SCRIPT>

This is simplest form of script that is possible. The above script will return the exact time of modification down to the hours, minutes and seconds. Variants of this script can make the output more "user-friendly". For example, if you wish to have an output as Month Date, Year (say July 4, 1998) only, it can be done by including the following segment of code in your HTML document:

Script 2.

<SCRIPT LANGUAGE = "JavaScript"><!--

function makeArray() { 
for (i = 0; i < makeArray.arguments.length; i++) 
  this[i + 1] = makeArray.arguments[i]; 
}

var modifiedMonth = new makeArray('January','February','March','April',
                          'May','June','July','August','September',
                          'October','November','December');

var modifiedDate = new Date(document.lastModified); 

document.write('Last Modified : ' + modifiedMonth[modifiedDate.getMonth() + 1] + ' ' + 
                                  modifiedDate.getDate() + ', ' + 
                                  modifiedDate.getFullYear());

//--></SCRIPT>

You can also introduce different colours and fonts to make the output more attractive. With a little bit of more work on the script, corresponding day and date suffixes (st, nd, rd, th) can also be added (so that the above example appears as Saturday, July 4th, 1998).

By adding appropriate functions for the day prefixes and date suffixes to the Script 2, and modifying the output the final form of Script 2 then becomes:

Script 2'.

<SCRIPT LANGUAGE="JavaScript"><!--

function makeArray() {
for (i = 0; i < makeArray.arguments.length; i++) 
  this[i + 1] = makeArray.arguments[i]; 
}

var modifiedMonth = new makeArray('January','February','March','April',
                                  'May','June','July','August','September',
                                  'October','November','December');

var modifiedDate = new Date(document.lastModified);

function modifiedDay(day) { 
      if (day == 0) return 'Sunday'; 
else  if (day == 1) return 'Monday';
else  if (day == 2) return 'Tuesday'; 
else  if (day == 3) return 'Wednesday';
else  if (day == 4) return 'Thursday'; 
else  if (day == 5) return 'Friday';
else                return 'Saturday'; }

function modifiedDateSuffix(date) { 
     if (date == 1 || date == 21 || date == 31) return 'st'; 
else if (date == 2 || date == 22)               return 'nd';  
else if (date == 3 || date == 23)               return 'rd'; 
else                                            return 'th'; }

function getCorrectedYear(year) {
    year = year - 0;
    if (year < 70) return (2000 + year);
    if (year < 1900) return (1900 + year);
    return year;
}

document.write('Last Modified : ' + modifiedDay(modifiedDate.getDay()) + ', ' + 
                                    modifiedMonth[modifiedDate.getMonth() + 1] + ' ' + 
                                    modifiedDate.getDate() + 
                                    modifiedDateSuffix(modifiedDate.getDate()) + ', ' + 
                                    getCorrectedYear(modifiedDate.getFullYear()));

//--></SCRIPT>

External JavaScript

With JavaScript 1.2-compatible browsers (such as Netscape Communicator 4.0+ or Microsoft Internet Explorer 4.0+), such scripts don't have to be included in the document directly and can be reused. All that is needed, is (a pointer to) the path to the file containing the script. However, you may have to configure your server and add a MIME type to your configuration in order to prevent it from returning a plain-text file. Including the following segment of code in your HTML document

<SCRIPT language="JavaScript 1.2" SRC="scripts/lastmodified.js"></SCRIPT>

where the file lastmodified.js contains any of the above portions of the scripts that are between the tags <SCRIPT LANGUAGE="JavaScript"><!-- and //--></SCRIPT>, and resides in the scripts directory.

Limitations

Unfortunately, it seems that the JavaScript technique doesn't work if the file is already using SSIs (say for some other purpose). That is, the above technique will not work if the file is of the type *.shtml and includes

document.write(document.lastModified)

Changing Techniques

One can use one of the above techniques or the other. Suppose we have a collection of files (over a file system) in which we previously used the SSI technique and want now to use the JavaScript technique. The task, after inserting the appropriate <SCRIPT> tag, then becomes of renaming these *.shtml files to *.html files. Using a Perl script this can be accomplished easily as follows:

Step 1. Copy (though maintain the copyright) the following script [Ref. 2] to a file, call it rename and change the path: #!/usr/bin/perl to wherever you have Perl on your system.

#!/usr/bin/perl -w
# rename - Larry's filename fixer
$op = shift or die "Usage: rename expr [files]\n";
chomp(@ARGV = <STDIN>) unless @ARGV;
for (@ARGV) {
$was = $_;
eval $op;
die $@ if $@;
rename($was,$_) unless $was eq $_;
}

Step 2. On the shell prompt (for UNIX platforms; on other platforms a variant of find should work) type the following where the directory_name is the top level directory (with subdirectories where *.shtml files are residing):

find ./directory_name -name '*shtml' -print | rename 's/shtml/html/'

Of course, the same idea applies if you wish to rename *.html files to *.shtml files:

find ./directory_name -name '*html' -print | rename 's/html/shtml/'

Y2K Compliance

In the server-side approach, the compliance depends directly on the operating system and hardware on which the script is being run.

In the client-side approach, use of getFullYear() assures the Y2K-compliance to a large extent, but requires (1) "appropriate" use of the Date() object, and (2) that the browsers support JavaScript 1.2 and above (to be precise, the ones that support ECMAScript as defined in ECMA-262 standard). The issue of Y2K-compliance in JavaScript will be addressed in detail elsewhere.

Conclusion

With some basic knowledge of SSIs or JavaScript, you can add customized timestamps to your HTML documents.

Please let me know if you have any comments, suggestions or questions about this article. Contributions for any additional techniques are most welcome.

Acknowledgements

I would like to thank Alan Liu, and particularly Dave Campbell, for their suggestions regarding Y2K compliance in JavaScript scripts presented here.

References

[Ref. 1] HTML: The Definitive Guide, 3rd Edition, By Chuck Muschiano and Bill Kennedy, O'Reilly & Associates, 1998.

[Ref. 2] Perl Cookbook, By Tom Christiansen & Nathan Torkington, O'Reilly & Associates, 1998, p. 327.

Related items

CGI Security : Better Safe than Sorry

Creating a Page Counter In Perl

Speed Thrills : CGI Please ... and Fast!

CGI Programming Made (Relatively) Easy Using Libraries

Server-Side Includes and its Extensions

Random and Recursive Crypting using Salt on Unix and Win32

Deleting Files in Perl

Creating a mailing list using Perl

Reading and Writing to Files on the Server

Server Side Includes and CGI Security

©2018 Martin Webb