What's Behind This Website?

Simplified Navigation

PHP has been a wonderful tool to simplify the coding of the left-hand navigation. I have opted not to use images in the navigation pane, mostly because they aren't easy to maintain. If a new menu item is needed, it can't be implemented without first creating a button image. Moreover, navigation buttons can be slow to load.

Therefore, the MaxText navigation is more or less text-based. Using the CSS effectively, I can achieve dynamic mouse-over effects without using Javascript (and more navigation button images.)

It is not unusual to see "brute force" techniques applied to get such navigation, whereby each item in the text-based navigation is hand-coded. Tweaking the look-&-feel of the navigation formatting requires each item to be edited individually to achieve consistency.

Instead, I use a PHP array to store the exposed name and the underlying URL. I then have PHP loop through the array and auto-generate the HTML for the navigation when the page is loaded.

I can use the same array to generate navigation that has:

A bulleted list.

"Fake buttons" using >DIV< tags and the CSS to achieve the button look.

A blank button image that CSS & HTML tricks can display in the background.

These options are still primarily text-based, which facilitates maintenance and navigation changes.

Regardless, my navigation is compartmentalized into its own file. I then use the "include" command on all relevant pages to have this file inserted into the content when they are loaded. This is one of my favorite commands because it removes clutter and distractions from the content of the individual source files. It is very similar to the link command for CSS so that it doesn't have to be embedded.

The advantages:

The navigation is localized to one file and "linked" everywhere.

The HTML coding to display all of the navigation items is localized to one instance within that file, instead of one instance for each navigation item.

The navigation items can be quickly added to, removed from, and renamed in the PHP array. Permits more frequent updates to keep the site fresh with new content.

Macromedia Dreamweaver employs what they call templates which also helps with the write-once/reuse-many-times paradyn. What I don't like about their templates are:

When you make a change to a template file, you have to push this into all referencing HTML files. Instead of uploading one file to reflect a common change, you might have to upload the entire site.

The referencing files embed the template information.

This can bloat all of the files on the site with common information.

Multiple authors working on a complex site would be better served if this common information were hidden from view, instead of distracting the writers from the new content they have to create for that page.

It gives the illusion that you can edit this template information.

Sometimes you can change that information for a given page at the cost of breaking the link (unknowingly) with the source template.

Sometimes the link remains in tact so that the next time the template is pushed to referencing files, your modifications get overwritten.

Their tool assumes that there is only one web master who serves as a bottleneck for all content. All postings are done from one machine. When multiple authors work on the site from other computers, they are required to have all relevant (template) files and an identical structure. It opens the door for broken template links and other synchronization problems.

Changing the Look-&-Feel with a Dynamic CSS

I've been in many situations where a seemingly small request from an influential person had huge ramifications in the documentation. Things like:

Changing the product name.

Changing the company name.

Changing the fonts used.

Changing the color attributes of things.

I've learned to steer clear of such problems by making more efficient use of my tools.

In the case of the Bells & Whistles look-&-feel functionality, I created it for my own use to help me compare quickly color and font options. One thing led to another, and I ended up inserting it into the navigation. It is one file which PHP includes into the navigation file, so can be backed out easily when I tire of it.

It works by defining PHP variables for colors, fonts, and images that get populated from the web form in the navigation pane. The normal CSS file was turned into a PHP file with key style elements defined from those variable values. This PHP-based CSS file then gets included into a common PHP file used by the entire site. When any page is loaded, the CSS information gets inserted directly into the generated HTML page but with the variable information resolved.

I would have preferred to keep the generated HTML cleaner by using a one-line link to a CSS file. Its problem is that external CSS files aren't run through the webserver's PHP processor to resolve the PHP variables. On the other hand, if the full content of the CSS file is included within a page, such PHP variables can be resolved. The compromise is that my PHP source files can remain clean and the CSS information can still be compartmentalized in its own file, while the HTML generated on the site becomes somewhat verbose with CSS style information.

Random Thoughts

Getting the Random Thoughts

The workflow for getting the random thoughts included on each page is rather complicated. Although it was an intellectual exercise to prove that I could do it, it wasn't without some real-world significance and money-savings. Specifically, MaxText was not established at the ISP with access to a database like MySQL, while another website under my control was. To get MySQL on MaxText would have meant yet another monthly fee. Just as importantly though, the information I wanted to display was needed on the other site as well. Even if MaxText had direct access to MySQL, did I want to duplicate the information in another database? No.

So here's the workflow for getting a single random quote displayed on a MaxText page:

A given parent PHP page on the site includes a PHP file with the "Random Thought" (RT) information. The parent can pass in variables to the RT file, such as the number of quotes to display. This in itself could have come from the Bells & Whistles forms included in the navigation page.

The RT file is pulled into select PHP pages with an include statement.

It contains some basic HTML formatting.

It defines an IFRAME, which has the ability of created a frame-within-a-page that displays different content. Perfect for the RT.

The information passed-in for the number of quotes is used to help size the IFRAME.

The IFRAME calls a CGI script with the quote information. This script is called the client application.

The client application performs several preparation tasks:

It parses any incoming variables, such as the number of RT to output.

It generates a SOAP request for a server application, making sure it includes any information that needs to be passed along.

It sends the SOAP request over the Internet.

The server application resides on another webserver that has access to the MySQL database. The server application performs several tasks.

It receives the SOAP request.

It parses any variables passed in, such as the number of RT to collect.

It generates an SQL statement applicable to the request.

It sends the SQL statement to the MySQL database.

It retrieves the results of the database call.

It parses the database results and formats it into an XML packet.

It sends a SOAP response with this XML packet of database results back to the client application.

Then the original client application continues with its operation by performing several more tasks.

It receives the SOAP response.

It parses the XML packet into its own internal data structure.

It generates the HTML tagging and formatting for each item in the XML packet.

It outputs this to the IFRAME.

This workflow could have been simplified on the client side, in that newer PHP versions support the SOAP protocol. However, my ISP has not installed these PHP versions. Their Perl installation, on the other hand, does include modules for SOAP.

It is not possible to have a CGI Perl file generate PHP code and have that code executed by the PHP processor, because the CGI bypasses the PHP processor. Likewise, a PHP file is not designed to kick-off a CGI script automatically and have the CGI and PHP content appear side-by-side. If my ISP's PHP installation would have supported SOAP, it would have been a non-issue. Given that my pages are PHP, my SOAP interface is through CGI (Perl), and the goals of the "Random Thought" feature, the IFRAME element was a convenient tool to get CGI content embedded within a PHP page.

The most difficult aspects of this implementation were:

Getting the client and server to talk to one another. At home. And then at the ISP.

Getting connected to the database. At home. And then at the ISP.

Just because I program something and test it on the Apache web server installed on my home computer, doesn't mean that I can plug it into my ISP's environment and expect it to fly without some modifications.

The ISP requires that CGI scripts reside in specific directories (other than cgi-bin) for security purposes.

When I couldn't get even simple CGI scripts to run on the ISP's server, their support personnel discovered some misconfiguration on their part.

The first line of the CGI scripts has the path to the Perl executables, which is different on my Windows environment from the ISP's Linux environment.

The CGI scripts need to have their permissions changed to executable in order to run. Not all of their tools for website updates would remember these settings.

It took me awhile to figure out that CGI scripts in Perl have to be saved in a Unix file format (that uses \n instead of \r\n at the end of lines). Interesting though, Perl packages that are called from the CGI script needed neither to be in a Unix file format nor to have executable permissions.