C-Scene Issue #3
Modular Website Design Using CGI
Dusty Trammell
First of all, I would like to state that this is more of a design article rather than an article about C, even though all code used in this website system was coded by myself in C. I won't necessarily go into code unless there is a specific reason, and if your not familiar with basic CGI, I would suggest reading the article "CGI Tutorial" by Brent York in Cscene #2, and also the book "CGI Programming on the world wide web" by O'Reilly & Associates, Inc.

To start off, let me explain the theory behind this websystem. The general idea is to minimize the size of the entire website so that it takes up as little space as possible, while also making global changes to the entire website possible with minimal effort. I have seen some systems that were similar, but none really did exactly what I wanted to do. The way I designed this system was to have a central CGI that runs the entire site. What this CGI does is simply check to see what it's name is, then based on it's name, grab chunks of html from given directories. The directory structure I use is:

In each of these directories there is a file simply named "default". Now I'm getting a little ahead of myself. First of all, we have the main CGI that grabs chunks of html, puts them together, and sends them via printf() to the webserver. I chose to name my engine "webit". Let's say that I want to create my main index page. I would create a link to webit called "index". Now for the main index page, you obviously have to set up your server to use the CGI as the default index and not look for index.html. My system only uses document root for such things as maybe an images directory or a files directory; ALL of the html is stored in chunks in the cgi-bin directory. If you do not know how to ScriptAlias your server to use a CGI as the default index page rather than index.html, I suggest you read the helpfile or FAQ for your webserver.

Ok, so now we have our server pointing to /cgi-bin/index as the default index page. Let me explain what index is and does. /cgi-bin/index, as I have said before is a link to webit. When the server executes /cgi-bin/index, the first thing it does is check it's name ( argv[0] == "index" ).

The first thing it outputs is the Content-Type line (once again, refer to CGI Tutorial in Cscene #2), and then looks at the /www/cgi-bin/headers/ directory. If there is a file that matches it's name (in this case, "index" ), the webit engine will grab that file and send it to stdout. If there is not a file that matches its name, it grabs the file called "default" and sends it to stdout. If "default" does not exist, a hardcoded version is sent to stdout.

Here is a quick example of how to do this:

sprintf( deffilename, "/www/cgi-bin/headers/default" );
sprintf( filename, "/www/cgi-bin/headers/%s", argv[0] );
spew_file( deffilename, filename )
Repeat the above for the headers dir, breakers, html, breakers again and then the footers dir. spew_file() consists of something like this:
spew_file( char *def, char *filename )
  FILE *f1;
  char buffer[1024];
  if( access( filename, 0 ) == 0 )
    f1 = fopen( filename, "r" );
    while( fgets( buffer, sizeof(buffer), f1 ) != NULL )
      printf( "%s", buffer );
    fclose( f1 );
    if( access( deffilename, 0 ) == 0 )
      f1 = fopen( filename, "r" );
      while( fgets( buffer, sizeof(buffer), f1 ) != NULL )
        printf( "%s", buffer );
      fclose( f1 );
      /* hardcode some html here... (: */
You get the idea...

This process is repeated for /www/cgi-bin/breakers/, then the /www/cgi-bin/html/ directory, then /www/cgi-bin/breakers/, and then the /www/cgi-bin/footers/ directory. By now you should be getting the general idea. Normally all pages on the site should use the default files in headers, breakers, and footers, unless you want that specific page to have it's own unique headers and footers, or for instance a page that is simply some frameset calls, in which you would want empty files for the headers, footers, etc. What this allows is on-the-fly building of each individual page as the user requests it. Let's say 40 people are accessing your website, and you decide you don't like the background color. Simply edit /www/cgi-bin/headers/default (where the <BODY> stuff would be), and change the background color. Instantly after saving the new version of that file, EVERYONE that accesses a page would recieve a page with the new background color. Also, this minimizes the size of the website, by eliminating the header and footer html from each individual page, and putting it in one place. Links to the engine cgi also allows for use of the same cgi engine over and over (saving space), yet having it react differently based on the link's name. Here's a quick breakdown of generally what I like to include in the default files:

	/www/cgi-bin/headers/default :
		<HTML>			The Open HTML tag
		<title></title>		The title tags
		<BODY>			Body tags, such as text color, 
						background color, etc.
		<center>		A center tag (I like all my pages
						to be centered.)
		<img src> or Text	Some header image or text, maybe
						something stating the
						Company Name, etc.

	/www/cgi-bin/breakers/default :
		<HR> or <img src>	Either a <HR> or bar image,
						something to break the
						header from the html.

	/www/cgi-bin/html/default :
		<img src>		An under construction image
						obviously, this page
						is linked to the driver
						but the html isn't ready.

	/www/cgi-bin/footers/default :
		<a href>		Some links to the main selections
						of the website.
		<a href=mailto:>	A mail link to the webmaster(s)
		Text			Some copyright info
		</center>		Remember <center> from the header?
		</HTML>			My close html tag.
Once again, the default files are only used if a html chunk by the same name as the link to the cgi does NOT exist. This way, you can make all your links to the cgi driver, and if you have not created the actual html for the /www/cgi-bin/html/ directory yet, it will use the default, which would be a page with an under construction symbol.

Alas, I grow weary of writing, and by now you should understand the concept. I will write a followup article to this one in the near future based on feedback from this article, attempting to explain what readers did not understand or wish me to elaborate on. But for now, I must get back to my code.

"May the source be with you..." Dusty Trammell

This page is Copyright © 1997 By C Scene. All Rights Reserved