Chapter 32

Classified Pages


The main theme of this chapter is to show how the Web interface can breathe new life into an old and successful tool: the classified ad. This chapter doesn't change the classified-ad model much but shows how the pages that support dynamic classified-ad systems are implemented. The chapter introduces issues related to page layout, decisions on how dynamic the system is (do you allow users to create new classifications?), and how to get two parties together to strike a deal through the Internet.

The chapter talks about three things related to the application "classified ad": first, the layout of the ad itself, second, how to go about deciding what parts of the application are dynamic (do you let the user create their own classifications, for example), and third, what about this application brings people together. For example, if someone is reading your ad, how do you program the application to provide a connection between the "customer" and "seller"? All of these issues are related to the way the classified ad application is designed and each of these issues comes up at certain points when you are designing the application's appearance and functionality.

The Classified-Ad Model

The classified-ad model doesn't need much explanation; everyone has seen the classified-ad section of a newspaper. The newspaper version of the classified ad has many features that we want to duplicate in the Web environment. We also want to incorporate some features into the Web-based classified ad to enhance the effect of the newspaper classified ad.

We can begin developing the Web-based classified-ad application, WebAd. The following specifies the feature list and expectations of the WebAd application:

The Mechanics of the WebAd Environment

The mechanics of the WebAd environment involve several pages. The entire environment is built around a recursive CGI script model. The environment also uses HTTP cookies as another example of where cookies are useful. Cookies allow user sessions to be tracked easily and efficiently. They can also be used to maintain data about a user throughout a session so that a user does not have to enter the same information multiple times.

The Classification Index

The first page that the user may see is the Classification Index page. The WebAd application can be reached at the following URL:

By default, if no arguments are passed to the CGI, the page displayed is the Classification Index page (see Fig. 32.1).

Figure 32.1 : The page has a list of all the classifications (linked to the specific classification) and a search entry box for finding items faster.

The Classification Page

If the user picks a classification (see Fig. 32.2), the next page in the WebAd environment is the specific Classification page. This page shows all the items in that specific classification. Additional links from the Classification page are

Figure 32.2 : Links to post a new item, go to other classifications, create a new classification, or search.

The Classification page is the main toolbox for the user. All the links possible in the WebAd environment. The WebAd environment would be dry without any items for users to look through, so to create new entries for a classification, users click the text post an ad for this classification. That action takes users to the page that asks for new ads.

The New Ad Page

On the New Ad page, we ask the user for the following information about himself and the ad he wants to post:

We need this information for administrative purposes.

The next questions asked are about the ad itself, as follows:

Figure 32.3 : The New Ad page lets you enter an ad. The contact information is added if you click the radio buttons.

The Classification Page (Again)

When items are visible on the Classification page, (for example, when after submitting a new item), the individual items are displayed three columns across (see Fig. 32.4). They fill the page vertically as needed. One interesting thing about the display function for each Classification page is the fact that each column is built separately-no wasted white space appears between horizontal rows. The application displays columns across the page first and then dynamically adds rows as needed. This ensures that the user can scan more classifieds with a minimum amount of scrolling and unnecessary whitespace.

Figure 32.4 : The Classification page is shown with several items posted to it. Notice how the vertical spacing is generated when no unnecessary white space is present below each item.

<table> <tr> <td> an item</td> <td>A lot of text, many many words that continue for a long time.. (insert 100 more words) </td> </tr> <tr>

In <td> (new column, second row), there is a lot of whitespace because the last column in the row above dwarfed the first cell (column 1, row 1). HTML tables make grids around cells (stuff between <td> and </td>) to fit the largest cell; if smaller cells are in the same row, whitespace is present under them. It's a waste of space. The classified-ad application builds columns rather than rows so that ads are stacked vertically and so divisions between columns are not orthogonal by row as well:

BAD: +----------------+ | one | two | | | three | | | four | +------+---------+ (all cells in row 1 are cut off by the | five | six | biggest cell in row 1, hence the two wasted +------+---------+ lines under "one" ) Good: +----------------+ | one | two | +------+ three | | five | four | +------+---------| | six | +---------+

This example might not make it clear since it takes more "ads" to show the long term savings of space. Essentially, the classifed-ad application does its best to stack them vertically. What would be really great is to write the application so that it uses body sizes to arrange "lots of short ads" alongside "big ads" to optimize screen usage (screen real-estate).

The routine for displaying the items uses the HTML TABLE tag, but there is only one "row" constructed and three "cells" in that row:

<table> <tr> <td> ... </td> <td> ... </td> <td> ... </td> </tr> </table>

The New Classification Page

This application allows users to create a new classification independently if they cannot find a classification that suits them (see Fig. 32.5). This feature probably would be protected from the users, however, so that no one except the Webmaster can create new classifications.

Figure 32.5 : In the New Classification page the user can select the new numeric classification and the text name to give that classification. If the number has already been used, it alerts the user to pick a new number.


The user types in a word into the search entry box labeled Concept. The CGI script scans all the items in all the classifications and generates a new custom Classification page that shows just the items that match the search criteria. The result page from the search looks exactly like the Classification page.

The Input Mechanisms

There are a few mechanisms for getting input from the user. The most important mechanism asks about new items to post. Other mechanisms for accepting input are handled by the search box and by the new classification prompt.

Three main areas of the WebAd environment accept input from the user:

The CGI script that implements the WebAd environment is split into two files. The first file is the CGI script, as listed in the URL. The CGI script uses a library file, which is the second file. The library file has all the main functions defined for the WebAd environment. The CGI script provides the simple logic for what type of page in the WebAd environment to display. The CGI script decides what kind of page to display depending on the data it receives from input. Some inputs are self-generated; other inputs are from the user. The self-generated inputs are based on URLs to itself with arguments to the CGI script dynamically placed in the URL. For example,

print "/cgi-bin/foo.cgi?variable=$someData";

The CGI script works as a recursive CGI script. Data passed to it, either in the URL or using the POST method, determines what kind of page to display. All page-display routines are in the Perl library in Listing 32.1.

Listing 32.1  WebAd.cgi-The Application That Generates the Pages for the Web-Based Classified-Ad Environment
#!/export/home/jdw/perl/bin/perl @INC = (@INC, '../../lib'); require ''; require ''; # states: # # new ad, display all classifications, display one classification, # new classification request %Form = &getStdin; %Cookies = &getCookies; # things we need to do before MIME gets sent. # lets give the user a break and remember who they are # so we don't bother them with this info more than once a day. $p = $patienceLevel = 86400; # one day if ($Form{'postnew'}) { if (! $Cookies{'c_name'}) { &setCookie('c_name', $Form{'c_name'}, '/', time+$p, '',0); &setCookie('c_phone', $Form{'c_phone'},'/', time+$p, '',0); &setCookie('c_email', $Form{'c_email'},'/', time+$p, '',0); &setCookie('c_addr', $Form{'c_addr'}, '/', time+$p, '',0); } } $ENV{'c_name'} = $Cookies{'c_name'}; $ENV{'c_addr'} = $Cookies{' c_addr'}; $ENV{'c_phone'} = $Cookies{' c_phone'}; $ENV{'c_email'} = $Cookies{' c_email'}; &beginHTML("WebAd","bgcolor=ffffff"); print "<h1>Chapter 32, WebAd application</h1>\n"; if ($Form{'promptclass'}) { &promptClass; } elsif ($Form{'newclass'}) { &handleClass($Form{'classnum'}, $Form{'classname'}); elsif ($Form{'search'}) { &handleSearch($Form{'search'}); &promptSearch; } elsif ($Form{'postnew'}) { &postAd(%Form); &promptSearch; } elsif ($Form{'aid'} && $Form{'create'}) { &createAd($Form{'aid'}); &promptSearch; } elsif ($Form{'aid'}) { &showCA2($Form{'aid'}); &promptSearch; } else { &showCA; &promptSearch; }

The functions that support the input mechanisms are

The Output Mechanisms

The output mechanisms for this application are rooted in the display of a specific classification. A classification has an ID number assigned to it.

Storing the Classified-Ad Pages

A directory is set up to hold all the classification data and the items in each classification. The location of this directory is stored in the variable $CAHome (classified-ad home). $CAHome has at least four files. One of those files is the index file for all valid classifications; the name of that file is stored in the variable $CAIndex. By default, the name of this file, which is a UNIX DBM file, is caindex (classified-ad index). The key for each element of caindex is the numeric classification ID. The value of each member of caindex is the text name of that classification.

By default, WebAd supports three classifications:

More classifications can exist, but they are added by the Webmaster or by the users of the WebAd environment (via the Web interface).

Each classification has its own DBM file. Each DBM file for each classification stores the data for all the items in that classification. The notation used for the DBM files is classification-ID, appended to the word class. The Help Wanted classification, for example, has the ID 200, so the classification DBM file for Help Wanted is 200class.

The display routines generate output work by loading all the elements from a specific classification file.

The key for each element in the classification file is the time of day, in seconds. The value is a binary packed structure of 10 elements. The variable $adTemplate contains the binary structure unpack format.

The elements, in order, are

Building a Page

A page is built by pulling up the specific DBM file needed. In the WebAd application, Perl is used to implement the functionality. The DBM file is accessed through an associative array when opened.

Each element is unpacked in random order and stored in a matrix. The subscripts of the matrix are the logical row and column in which the element would be displayed if the output were built row by row.

The output of each classified page is built column by column because we don't want wasted space in each row. If the output is built row by row, more than one row is defined in the HTML table. The cell in the row that has the most content sets the outer boundary for the vertical spacing used in that row. If there is a large cell to fill, the browser stretches the cell height for its size. The other cells in the same row have gaps below their paragraph information until the next row starts. The output routine avoids the excess of whitespace by first computing the matrix of classified cells as if the output were to be created row by row. The application then puts the cells in the same order, one column at a time.

The displayArticles() function builds the matrix of cells and then translates it into a new format: three columns (each a stack of cells) with no wasted space between cells.

The cells themselves have a format, too. The first string in the cell is the leader text, in bold type. Immediately following the leader text is the paragraph text. Below the paragraph is a set of optional lines. Depending on the flags set on the New Ad page, up to four additional lines are possible:

Each cell is itself a table with just one row and a border value set to 1. This condition has the effect of putting a line around each cell contained by the larger-scope HTML table.