The World Wide Web has been around for several years now and is one of the largest used resources for information on the Internet. Nowadays the problem isn't so much getting the information there but sorting, formatting, and displaying it in such a way that it can be digested easily. A common practice for displaying large lists of information that have a common structure is using repeated HTML tables, e.g. lists of books for a library, project listings, quotations.
Python is an excellent server-side scripting language with all of the capabilities to construct extendable and robust CGI programs to format, sort, and display these sorts of information on the WWW. I came into using Python after a long debut of using Perl for the same tasks. Though Python is easier to read and understand than Perl in most cases I had one complaint about Python that Perl did easily for me: The HTML code for a page could be imbedded directly into the program without fuss. In Perl all that has to be done is to define a block of HTML code with variables, etc. imbedded in it. This isn't possible with Python; you must use repeated print statements for each line of the HTML document to display it.
The solution to this problem that first came to mind was to use Templates, or already generated HTML documents with key-words imbedded in them to tell the Python script to put its information in that location. Because of Python's powerful line-by-line file i/o functions this is made extremely simple.
First the program should import the proper packages:
import sys, os, string
Next, taking advantage of the Object Oriented design of Python, an object class that shall contain the information that will be displayed in each table of information in the HTML file is generated. This Object should be able to load the data from the target storage medium (for simplicity a pipe, '|', delimited file in this case,) and print the tabular HTML version of itself when called to do so.
The example as follows generates its own table code, but given more complex formats could also load from a template file as per the concept being demonstrated:
# Include all of the variables here so that if this object is
# ever extended (unlikely) they will be accessible by its
title = '
author = '
summary = '
self.title = 'No Title Given.'
self.author = 'Author Not Entered.'
self.summary = 'No Summary Entered.'
def read(self, file):
line = file.readline()
if not line:
return 1 # End of book listing reached, return.
elif not string.strip(line):
continue #Empty line.
[self.title, self.author, self.summary] = string.split( line, '|' )
|" + self.title + ""
|" + self.author + "|
|" + self.summary + "|
An easy access function for displaying the entire set of tables is also necessary. This code will load each BookInfo object with the appropriate data from the data file and then display the entire group in HTML once they've all been read.
if not os.path.isfile('./book.dat'):
print "Failed to locate book.dat."
bookfile = open('./book.dat', 'r')
Books = 
count = 0
count = count + 1
The main section of the program simply opens the template file, loops through each line of the template file and prints it unless it contains the trigger to place the tables in that location. In this case the trigger is an HTML comment (so that if it fails to find the trigger it doesn't show up to the viewer.) It may be easier to debug if it wasn't a comment, that way it would display on the page, but if an error occurs (i.e. it doesn't find the trigger) no tables will be displayed, which should be obvious.
# Begin by setting this aside in the Python program only to run
# when it is called on execution.
if __name__ == "__main__":
# Output the HTML header (this is a CGI script.)
print "Content-Type: text/html\n\n"
# Simple handling for failure to locate the proper template file.
if not os.path.isfile('./template.html'):
print "Failed to locate template.html."
# Open the primary Template file for reading.
templateFile = open('./template.html', 'r')
# Main loop begins here:
line = templateFile.readline()
# If the end of the Template is reached then exit
# this loop.
if not line: break
if string.strip(line) == '':
displayProjectTable() #Display the tables on trigger.
print line, #Otherwise display tables.
Here is an example data file (book.dat):
HowTo Python|James Smith|A simple description of the Python programming language and some fun examples.
Terra Incognita|Earth|A look from life on other planets at life on this one.
Here is an example HTML Template file for this (template.html):
Python Easy Tables
This together will produce a drab looking web page when called as a CGI from a web URL. This is mostly because the template file has absolutely no glitz or sparkle to it, nor do the tables that are being generated. It wasn't useful to put that into this demonstration. However, it should adequately display the concept. Another nice thing about doing it this way is that the BookInfo objects can also be used to display even more information (or gather more if they were modified to do so.) The template file can have all type of further style placed into it. It could generate a larger table to hold the book information tables, give links to other pages, display the time of day, etc. The script governs none of this, all the script does is produce the tables according to the data file. That data file could even be changed, or the place that the data is being received from. In fact, a database query could be used in place of the 'read' section of the BookInfo object if necessary.
This technique gives way to any number of useful modifications. In another project that this technique was used not only did I have it display all of the information in tables, but in a sidebar the titles of each table was also displayed. This was so that the viewers could see the list before they looked further over the page.