In a World Of Databases, ASP and Text Files

Sunday Jan 24th 1999 by ServerWatch Staff
Share:

Plain text files offer some advantages for online applications using changing data. The idea of this series of articles is to explain some of the better tricks for using plain text files, or comma and tab separated lists to support dynamic data sources for the internet.

T.Mallard


Plain text files offer some advantages for online applications using changing data. The idea of this series of articles is to explain some of the better tricks for using plain text files, or comma and tab separated lists to support dynamic data sources for the internet. These concepts can be used for Enterprise platform hopping as well as small business needs. A basic premise of this work is that these data files are read-only to the world as typical HTML pages are. This prevents users from altering data and allows 7x24 on-the-fly updating using FTP by publishers.


Output from this code.
The Latest
How do you keep all those messy pages up to date without a zillion concurrent users pounding your database? Like the idea of ad rotators, any site has a lot of dynamic data over time which can be reduced to classic (row,column) data. The best place to start for this is of course navigation, yet also consider ASP's Dictionary object in conjunction with text files to create easy to search, easy to update systems. This will also be explained in the series of articles.

Updating URL's for Navigation
Let's presume to have a navigation frame with links to other pages on the site. If these are kept in a text file and delivered dynamically to clients, they can also be used for other reasons by the website without altering the actual HTML pages. Using data this way increases exposure of your data which reduces the resource demand of keeping up to date.

Creating the Object
In this case, there is the need to create a file system object associated with the URL list. This is created using a readline routine that transfers the field into the navigation page as it is created. Typical code for this would look like:

dim objfile, navfile
set objfile = createobject("Scripting.FileSystemObject")

Does Object exist? If yes, open the file:

if isobject(objfile) then
set navfile = objfile.opentextfile("D:\webshare\wwwroot\asp\nav.txt")
An error can occur here if the file isn't found, or can't be opened by the system so having an 'on error' statement is important to keep the client application from hanging. To handle this error one could use a default list in memory which was included at runtime, or hard-coding URL's which are used on file system error. The entries for the text file or these alternatives would look something like:

<a href=" default.htm">homepage</a>
<a href="products.htm">products</a>
<a href="prices.htm">prices</a>
<a href="technical.htm">technical</a>
<a href="white_papers.htm">white papers</a>
<a href="support.htm">support</a>
<a href="archive.htm">archive</a>

The code now has nav.txt open in read-only mode if there wasn't an error. To read a line you code a statement:

while not navfile.atendofline
dim nav
nav = navfile.readline

Since this delivers the value we want for a URL, modify the statement to create a line of HTML output to the page.

response.write("<a href=' " & nav & " 'target='main'>" & nav & "</a>")

This is now ready to use in a loop which will create the links to pages which are going to be sent to the target frame "main". To send this page a typical HTML page is created with response writes.

<%@ language="vbscript" %>
<% response.buffer = True%>
<%
dim objfile, navfile
set objfile = createobject("Scripting.FileSystemObject")
if isobject(objfile) then
set navfile = objfile.opentextfile("D:\webshare\wwwroot\asp\nav.txt")
end if
response.write("<!-- DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 3.2 Final//EN'-->")
response.write("<html>")
response.write("<head><title>Website Navigation Page</title>")
response.write("</head>")
response.write("<body>")
response.write("<font face='verdana,arial,helvetica' size='2'><table border=0 cellpadding=6>")
while not navfile.atendofline
dim nav = navfile.readline
response.write("<tr><td bgcolor=ccffcc><a href=' " & nav & " 'target='main'>" & nav & "</a></td></tr>")
wend

response.write("</table></body>")
response.write("</html>")
navfile.close
set objfile = nothing
%>

What this code does
It creates a full HTML page which the top level frames page uses for navigation. The actual links used are from a text file somewhere on the server so to update them one simply replaces the text file. This is a simple example of using text files as an introduction to a very useful and versatile concept. The next article will build on this navigation page idea by explaining how to use this technique to fill select boxes.

T.Mallard




Fast fill-ups, ASP and Text Files






The select box.
Putting dynamic data into select boxes at runtime is very similar to the previous example. But this time a Dictionary object is created to focus on a likely scenario in production. The reason is the Dictionary object allows some functions which are very useful by the fact they emulate a database. Other pieces are the page header and body containing the form, and a footer. Many of these pieces are typically server side includes as well, but to illustrate the versatility of the text file, I'll use text files instead of includes for the header and footer for this sample code.

The key to it all
An easy way to create useful data is to organize it in key/value pairs. ASP's Dictionary object's properties are CompareMode, Count, Item and Key, and the methods are Add, Remove, RemoveAll, Items, Keys, and Exists.

Using key=URL and value=topic
Let's presume to have a select box with links to other pages on the site and the topics of each. We'll want to display the topic and use the URL to redirect on the choice of the user. Both of these are stored as key/value pairs. The construction of the object is to set the properties and then execute the creation of the object.

There are rules to the game which help control data quality. Data errors are produced by two conditions: If a key already exists when adding; or, a key isn't there when removing. Three compare modes are possible: vbBinaryCompare, vbTextCompare and vbDatabaseCompare. These are handy.

Creating the Object
In this case, typical code to create the Dictionary object would look like:

dim dicKey, dicVal, dicObj
set dicObj = createobject("Scripting.Dictionary")

So, the next step is to create a file system object and open it to get the data for the dictionary.

dim navfile, fileObj
set fileObj = createobject("Scripting.FileSystemObject")
Did the object get created? If yes, open the file:

if isobject(fileObj) then
set navfile = fileObj.opentextfile("D:\webshare\wwwroot\asp\nav2.txt")
As before, an error can occur here if the file isn't found, or can't be opened by the system so having an 'on error' statement is important to keep the client application from hanging. To handle this error one could use a default list in memory which was included at runtime, or hard-coding URL's which are used on file system errors (404's). The error code to create a default dictionary would look something like:
on error resume next
dicObj.item("default.htm") = "Industrial Design and Other Interests"
dicObj.item("products.htm") = "An Interesting Array of Products"
dicObj.item("prices.htm") = "Current Pricing"
dicObj.item("technical.htm") = "Technical Details of All Products"
dicObj.item("white_papers.htm") = "White Papers Outlining Features and Scope"
dicObj.item("support.htm") = "Contact Our Friendly Support Crew"
dicObj.item("archive.htm") = "Dive Into the Archives for Facts"

The code now has nav2.txt open in read-only mode if there wasn't an error. To read a line you code a statement:

while not navfile.atendofline
dim nav
nav = navfile.readline

We need to separate this string which is separated by a comma. The instr() and mid() functions are the basic tools of parsing strings. Instr() is used to find a place, and mid() is used to retrieve it. With two variables, two mid()'s will retreive the key and value. This may seem like a lot of work...
dim comma, start, length, aurl, atopic
start = instr(nav, comma)
length = len(nav)
aurl = mid(1, start)
atopic = mid(start+1,length)
Now all the pieces are ready to build the dynamic part of the coding. This example continues the navigation theme, but it can be useful for many other items, especially graphic libraries. The number of columns is one of the limiting factors in using text based data. Knowing this, it's still common to be able to create data structures with two to five columns.
response.write("<option value=' " & aurl & " '>" & atopic & vbCrLf)

The next part is consideration of how to build the client page. If we want to use this box to redirect, it's handy to store the url's as option values and then use those on the client with javascript to redirect without using another server hit. The code above lists the option part of the select box, the javascript is hard-coded into the response writes. Note the single quotes within these write statements for normally double quoted attributes.

<%@ Language="VBScript"%>
<% response.buffer = True%>
<%
response.write("<!-- DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 3.2 Final//EN'-->" & vbCrLf)
response.write("<html>" & vbCrLf)
response.write("<head>" & vbCrLf)
response.write("<title>Fill Those Select Boxes</title>" & vbCrLf)
response.write("<script language='JavaScript'>" & vbCrLf)
response.write("<!--" & vbCrLf)
response.write("function gothere(){" & vbCrLf)
response.write("var aurl = nav.nav.value" & vbCrLf)
response.write("location.href = aurl" & vbCrLf)
response.write("}" & vbCrLf)
response.write("//-->" & vbCrLf)
response.write("</script>" & vbCrLf)
response.write("</head>" & vbCrLf)
response.write("<body bgcolor=ffffff link=0000ff vlink=8e2323 alink=00009c>" & vbCrLf)
response.write("<basefont face='verdana,arial,helvetica' size=2 color=000000>" & vbCrLf)
response.write("<form name='nav'>" & vbCrLf)
response.write("<font size=6 color=800000 face='Arial,Helvetica,Verdana'></font><br>" & vbCrLf)
response.write("<table border='1' cellspacing='2' cellpadding='12'><tr><td>" & vbCrLf)
response.write("<select name='nav'>" & vbCrLf)
%>
<%
dim dicKey, dicVal, dicObj
set dicObj = createobject("Scripting.Dictionary")
dim navfile, fileObj
set fileObj = createobject("Scripting.FileSystemObject")
if isobject(fileObj) then
set navfile = fileObj.opentextfile("D:\webshare\wwwroot\asp\nav2.txt")
end if
while not navfile.atendofline
dim nav
dim comma, start, length, aurl, atopic
comma = chr(44)
nav = navfile.readline
start = instr(nav, comma)
length = len(nav)
aurl = mid(nav, 1, start-1)
atopic = mid(nav, start+1)
response.write("<option value=chr()" & aurl & "'>" & atopic & "<br>")
length = 0
start = 0
wend
response.write("</select></td><td>")
response.write("<input type='Button' value='GO' onclick='gothere();' style='font-weight: bold; font-family: arialblack; color: white; background-color: Red; padding: 3;'></td></tr></table>")
response.write("</form>")
response.write("</body>")
response.write("</html>")
navfile.close
set fileObj = nothing
%>
What this code does
It creates a select box for navigation. The displayed list is from a text file with two columns separated by a comma. The page uses client side javascript to send the user to the topic selected. The coding uses a Dictionary object to store the URL and topic description, the next article shows how to use this object for database emulation of larger text files and arrays.

T.Mallard

Dyno default.asp, ASP and Text Files

So now most all of the default.asp homepage has been assembled by opening simple text files and filling the areas with the text file content. Suddenly this whole page can be left alone for long periods of time. If you make a mistake in the text file, this normally won't affect operations at all. Your customers may think twice...oooops.

The homeboy.

Ok, there's no browser checking, just a little code for noframes, this is very basic. Most developers of websites must be concerned with the user viewpoint and supporting the content for a variety of browsers is a fairly common procedure. There are two strategies for this, send javascript to the client and document.write at the places on a page where browser detection is needed; or, detect from the HTTP headers what browser is making the request and send a static page.

What the overall design intends to do has a great influence on the presentation of the page. Design elements in this case were composed of frames. The text file system can also produce composite single pages with this same source material. This would avoid the frames issue entirely by producing a page with tables instead.

To begin, the code for the banner is simple, just some font tags.

<div align="center"><b><font face="Book Antiqua" size=4><font size=6>O</font>nline<font size=6>A</font>rticles and <font size=6>P</font>hotography</font></b></div>

In this example the main page is constructed in pieces as before. The graphic used is the ASP ad rotator component, the text is in a separate text file with the footer table also a separate file, and all this will now be used to produce a set of tables to replicate the look of frames. The tables only here allow the content to be seen by almost any browser, which is best for a homepage.

The code

Creating a default.asp
In this case, typical code to create the frames version of the page:

<!-- DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 3.2 Final//EN'-->
<html>
<head>
<title>Outdoor Photography and Other Interests</title>
</head>
<frameset rows="44,*" frameborder="yes" framespacing="1" border="1">
<frame name="banner" src="banner_01.asp" marginwidth="3" marginheight="3" scrolling="auto" frameborder="no">
<frameset cols="106,*">
<frame name="nav" src="nav_01.asp" marginwidth="3" marginheight="2"
scrolling="auto" frameborder="no">

<frame name="main" src="main_01.asp" marginwidth="6" marginheight="6"
scrolling="auto"frameborder="no">

</frameset>
<noframes>
<body>
Your browser does not support frames so won't be able to view this website, please download an up to date browser as no text-only navigation is available.
</body>
</noframes>
</frameset>
</html>
Examining the main page, it has a content text file, then the ad rotator and finally the footer is added from another text file.
dim main_obj, main_file, main_content
set obj_ad = server.createobject("Scripting.FileSystemObject")
set ad_file = obj_ad.opentextfile("D:/webshare/wwwroot/asp/examples/main_content.txt")
on error resume next
main_content = ad_file.readall

This has the file main_content.txt open and moved into the variable main_content. Next I'll insert the ad rotator which is supported by two other test files!! These control what images are displayed and the URL's for links. The first of these is called the schedule file as it defines the amount of relative time each ad gets, as well as the graphic size and sources:

REDIRECT ad_urls.asp
WIDTH 96
HEIGHT 64
BORDER 1
*
/gifs/xcntry_01.gif
http://tommalla/asp/examples/default_4.asp
Online articles and photography
2
/gifs/xcntry_02.gif
http://tommalla/asp/examples/default_4.asp
Other online articles and photography
2
As you can
dim mainfile, fileObj
set fileObj = createobject("Scripting.FileSystemObject")
Did the object get created? If yes, open the file:

if isobject(fileObj) then
set mainfile = fileObj.opentextfile("D:\webshare\wwwroot\asp\main_content.txt")
As before, an error can occur here if the file isn't found, or can't be opened by the system so having an on error statement is important to keep the client application from hanging. To handle this error one could use a default list in memory which was included at runtime, or hard-coding URL's which are used on file system errors (404's). The error code to create a default dictionary would look something like:
on error resume next
dicObj.item("default.htm") = "Industrial Design and Other Interests"
dicObj.item("products.htm") = "An Interesting Array of Products"
dicObj.item("prices.htm") = "Current Pricing"
dicObj.item("technical.htm") = "Technical Details of All Products"
dicObj.item("white_papers.htm") = "White Papers Outlining Features and Scope"
dicObj.item("support.htm") = "Contact Our Friendly Support Crew"
dicObj.item("archive.htm") = "Dive Into the Archives for Facts"

The code now has main_content.txt open in read-only mode if there wasn't an error. To read a line you code a statement:

while not mainfile.atendofline
dim main
main = mainfile.readline

Again we need to separate this string which is separated by a comma. Instr() is used to find a place, and mid() is used to retrieve it. With two variables, two mid()'s will retreive the key and value.
dim comma, start, length, aurl, atopic
start = instr(main, comma)
length = len(main)
aurl = mid(1, start)
atopic = mid(start+1,length)
Next, main_01.asp uses the ad rotator (which only rotates on refresh).
dim obj_ads, ad_border, ad_click, ad_content2
set obj_ads = server.createobject("MSWC.AdRotator")
obj_ads.Border = (1)
obj_ads.Clickable = (True)
obj_ads.TargetFrame = ("_top")
ad_content2 = obj_ads.GetAdvertisement("ad_content.txt")
response.write(ad_content2)
For redirecting the urls, this coding is used.
dim gothere
gothere = request.querystring("url")
response.redirect(gothere)
Then there is the footer, stolen from another text file of course.

dim ad_obj, ad_file, ad_content
set obj_ad = server.createobject("Scripting.FileSystemObject")
set ad_file = obj_ad.opentextfile("D:/webshare/wwwroot/asp/examples/footer_01.txt")
on error resume next
ad_content = ad_file.readall
response.write(ad_content)
It looks like all the pieces are ready to build the dynamic part of the coding now. I'll have to create a master table and plot layouts to get a similar design to the frames version. This is nested tables, with the choice of either specifying percentages or absolute size in pixels as the usual methods of doing this. The outer table is a 100% wrapper with the first row the banner.
<table width=640 border=1 cellspacing=2 cellpadding=6>
<tr><td colspan=2 align="center" valign="middle"
bgcolor="White">banner</td></tr>
<tr><td width=48 rowspan=3 align="center" valign="top" bgcolor="White">nav</td><td width=592>main</td></tr>
<tr><td>rotator</td></tr>
<tr><td>footer</td></tr>
</table>
Seems to look about right. So, to assemble the page dynamically, these pieces will flow together as below.
<%@ Language="VBScript"%>
<% response.buffer = True%>
<%
response.write("<!-- DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 3.2 Final//EN'-->")
response.write("<html>")
response.write("<head><title>Website Navigation Page</title>")
response.write("</head>")
response.write("<body>")
response.write("<font face='verdana,arial,helvetica' size=2>")
response.write("<table width=640 border=1 cellspacing=0 cellpadding=1>")

dim abanner, bannertext, fileObj
set fileObj = createobject("Scripting.FileSystemObject")
if isobject(fileObj) then
set abanner = fileObj.opentextfile("D:\webshare\wwwroot\asp\examples\banner.txt")
bannertext = abanner.readall
end if
response.write("<tr><td border=1 colspan=2 align=center valign=middle bgcolor=ffffff>" & bannertext & "</td></tr>")
abanner.close
set fileObj = nothing
%>
<%
response.write("<tr><td width=48 rowspan=3 align=center valign=top bgcolor=ffffff>")
dim objfile, navfile, navout
set objfile = createobject("Scripting.FileSystemObject")
if isobject(objfile) then
set navfile = objfile.opentextfile("D:\webshare\wwwroot\asp\examples\nav.txt")
end if
while not navfile.atendofline
dim nav
nav = navfile.readline
navout = navout & "<tr><td bgcolor=ccffcc height=24>" & nav & "</td></tr>"
wend
navtable = "<table>" & navout & "</table>"
response.write(navtable & "</td><td width=592>")
%>
<%
dim main_obj, main_file, main_content
set main_obj = server.createobject("Scripting.FileSystemObject")
set main_file = main_obj.opentextfile("D:/webshare/wwwroot/asp/examples/main_content.txt")
main_content = main_file.readall

dim obj_ads, ad_border, ad_click, ad_content
set obj_ads = server.createobject("MSWC.AdRotator")
obj_ads.Border = (1)
obj_ads.Clickable = (True)
obj_ads.TargetFrame = ("_top")
ad_content = obj_ads.GetAdvertisement("ad_content.txt")

dim foot_obj, footer_file, footer
set foot_obj = server.createobject("Scripting.FileSystemObject")
set footer_file = foot_obj.opentextfile("D:/webshare/wwwroot/asp/examples/footer_01.txt")
footer = footer_file.readall

mainout = "<table><tr><td>" & main_content & "</td></tr><tr><td>" & ad_content & "</td></tr><tr><td>" & footer & "</td></tr></table>"
footer_file.close
navfile.close
ad_file.close
set main_obj = nothing
set foot_obj = nothing
set objfile = nothing
response.write(mainout)
response.write("</td></tr></table></body>")
response.write("</html>")
%>

What this code does
It creates a select box for navigation. The displayed list is from a text file with two columns separated by a comma. The page uses client side javascript to send the user to the topic selected. The coding uses a Dictionary object to store the URL and topic description, the next article shows how to use this object for database emulation of larger text files and arrays.

Share:
Home
Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved