Under the Hood
The main difference between this implementation and the previous implementation is our use of a server module called iHTML 2.1 Lite made by Inline Internet Systems, Inc.. This module allows us to do things like query databases through ODBC data sources and display a dynamic menu bar at the bottom of every page.
General Interaction of Components in this Implementation
This diagram depicts the general interaction between components in which a client requests a document from the web server. We start in the top right corner of the diagram. Here, the client web browser requests a document from the web server. The server then gets the requested document from the file system and prepares to serve the document back to the client that requested it. But before the document gets served, the iHTML module is allowed to look at the document. The iHMTL module determines whether or not the <iHTML> tag exists at the top of the document. If no tag exists, it then simply passes the document on and the document gets served to the client in the normal way. If the tag does exists, however, the iHTML module then parses and processes the document. In the case of directives that indicate database queries, it will make those queries and build a new HTML document based on the current document and the iHTML directives contained in the current document. After completing this new augmented document, this document is then served to the client.
ODBC stands for Open Database Connectivity. It attempts to provide a common interface for talking to databases. ODBC queries are written in SQL (Structured Query Language). ODBC has many database drivers that let it talk to different databases, but you don't have to worry about that. You just write your queries according to the ODBC interface and then ODBC worries about translating your ODBC query into a query that is specific to whatever database your DSN (Data Source Name) points to. So, in theory, you can write you query for ODBC and have it work for many databases without changing anything. If you should decide to migrate you current database to a different database, that is no problem since you are only talking to ODBC and ODBC handles talking to databases. Simply set your ODBC DSN to point to your new database and everything should work just as before.
iHTML Server Module
The way iHTML works is that it sits running on the server and it looks at the first line of every web page the web server serves out. If it finds the special directive <!iHTML> it then processes the whole document before it gets served to the client that requested the document. If the iHMTL module does not find the special directive, it does not do anything and the web server serves the document in its normal way. iHTML supports many directives (more and more directives if you get more expensive versions of the software). We will only mention some of the main directives as is needed by our discussion here. However, iHTML does come with a complete specification of all the directives should you want to find out more.
Database Connectivity with iHTML Lite
To query a database using iHTML, you simply need to set up an ODBC data source and then write a single HTML document including the necessary iHTML directives for the database query. Rather than trying to explain this in prose, I think it is much better to look at an example and then walk through what the example does. We create a file named
projects.html with the following content:
<iSQL DBNAME="ResearchDSN" SQL="SELECT SiteName, ProjectName FROM [ResearchProjects]">
Site name: <b>:1</b><br>
Project name: <b>:2</b><br>
When you access this
projects.html document from the web, iHTML will run a database query and return to you an HTML document that contains a list of site name and project pairs that were queried from the database.
Let's look at what is going on in this file. The first line, we already know about. It is the iHTML directive that tells the iHTML module to process this document. Without this directive, there would be no database query and a web browser would have no idea as to what some of the directives mean. Next, we have 3 lines of HTML and after that, we get into where the real stuff happens.
The <iSQL> tag has two arguments,
DBNAME is the name of the ODBC data source that points to the correct database.
SQL is the SQL statement that is used to query the database and select what you want the database to return. In this case the SQL statement says, "I want you to return all the values of the
ProjectName fields in the
The next tag is <iSQLFETCH>. This tag tells iHTML to get the first pair of values based on the database query. Next we see an <iWHILE> tag. This tag says, "While there are still more value pairs waiting to be returned from the query, do everything between here and the </iWHILE> tag.
Next, we actually put the values that are returned from the database query into the HTML that will eventually be returned to the client that requested the document.
:1 refers to the value of the SiteName and
:2 refers to the value of the ProjectName. Those values will be inserted in place of the
<iSQLFETCH> simply tells iHTML to get another set of value pairs for the next iteration of this loop. </iWHILE> is the end of the while loop. And
</iSQL> closes the database connection.
That's it. The rest is just HTML.
Dynamic Menu Bar with iHTML Lite
The menu bar that you see at the bottom of every page is dynamically generated by iHTML. You may say, "Well...what's dynamic about it, it looks the same every time to me?" And you're right; its appearance does not change. But its functionality does.
When it came to this menu bar, we had one intention, and that was to avoid having the HTML for the menu bar at the bottom of every single HTML document. The reason for this is that if you wanted to change a single thing about the menu bar, you had to change it in every single HTML document. We wanted the source for the menu bar to live in one spot and have all the HTML documents just read the same file for the menu bar. That way, if you change the source file, all of the HTML documents reflect this change automatically becuase they read this one file. To do this, we used iHTML.
Now, you may be thinking, "Why not just use an <INCLUDE> tag that most servers understand?" The reason is that this can only include a static file. We needed our menu bar to be dynamic because we have documents in different levels of the directory hierarchy. Clicking on a menu bar button that takes you back to the main
index.html page may simply require the path
index.html, or it could require the path
../../index.html depending on where in the directory hierarchy this current HTML document lives. There are atleast two other ways around this, but neither were acceptable. The first was to put all the HTML documents in the same directory level (i.e. all the files in one directory), but this is just a mess and would be horrible to try to maintain. The second solution was to give each <a href> tag an absolute URL as opposed to a relative URL path. This was not acceptable either because we wanted to deploy something that would "work out of the box". We did not want anyone who used this system to have to change the absolute URL in this include file when they installed it on a server to reference their server specifically. And worse, if they decided to change the server name, or move this system to a different location, they would have to change the absolute URLs again.
As was stated earlier, to solve this problem, we used iHTML. At the bottom of every HTML document, there are two iHTML directives that enable the menu bar functionality. They look something like this:
<iEQ name=poffset value="../">
<iINCLUDE NAME="includes/footer.html" PARSE="true">
The <iEQ> tag allows you to assign a value to a variable. In this case, assign the string "../" to the variable
poffset. The <iINCLUDE> tag tells iHTML to include another file at this point. The value of the
poffset variable essentially specifies the path to get back to the main directory from the current directory. So, for those HTML documents that live in the main directory (i.e. the directory where the
index.html file lives), their
poffset variable would have the empty string as its value. Within the included file,
footer.html, the value of
poffset will be prepended onto any URL paths appropriately. Thus, when the final HTML document is sent to the client that requested it, the menu bar works correctly, regardless of where in the hierarchy it lives.