[Prev] [Next] [Top] [Bottom] [Contents] (4 out of 22)

HTML Markup and Sapphire/Web CGI Clients

When working with Sapphire/Web it is important to understand the mark-ups the tool performs on your HTML. Sapphire/Web binds your Data Objects to your HTML files. Activators are HTML Anchors and Forms. To create an Anchor enter the following HTML fragment:

<A HREF="AnchorName">Title</A>
When you select this Anchor as an activator, Sapphire/Web will rename the Anchor, for example, as follows:

<A HREF="http://cezanne/cgi-
bin//popcall.cgi?FNC=authors__Asamp_html">Title</A>
The HREF has been changed to call your CGI with an argument. The first part of the HREF, up to the "?" is the Universal Resource Locator (URL) of your CGI. The pathname is from the "test.CGI URL" option for the project with the CGI's executable name appended. The part after the "?" will be either argv[1] to your CGI, or the contents of the "QUERY STRING" environment variable. You can use the argv[1] approach for debugging. In the above example type this at the command:

cgi-exec-name 'FNC=authors__Asamp_html'
The CGI will print to standard out what it would have sent back to the HTML browser. In the xxgdb debugger I type:

run FNC=authors__Asamp_html
and debug the CGI.

The HTTP server will most likely set the "QUERY_STRING" environment variable. Either way the CGI will read the part after "FNC=". This is the String Name that is used to lookup the "Activator" function for that bound Anchor. The Function Name, Aauthors, is a Static Function written in the HTML-related module. This is the name of the Anchor with "A" prepended. The string name authors__Asamp_html is used as a lookup to invoke the function Aauthors. This string name is derived from the anchor name and the modified HTML filename with "__A" inserted between.

The registration of that Lookup String is in the registration function for that HTML related module. The registration function is not static, it is called from Main, and would have the name R_samp_html in this case. This name is derived from the modified HTML filename with "R_" prepended. Of course, Sapphire/Web performs all this markup and naming transparently. The Activator Function is then invoked executing each of your Data Object requests.

Now, there are two different methods in which to run, depending on whether or not you are using HTML templates. Templates are described first, then the alternative method. If you have bound a column to a Data Site in the Object Bind Editor then you are using HTML templates. The Sapphire/Web CGI will then carry out all Object Requests and store the results in the CGI's memory. All templates encountered from the Bound Sites are added to a list of HTML template files to "play". Duplicates are eliminated. The HTML files are played in the order in which they were added.

Although Sapphire/Web supports the use of multiple templates per Activator Function, you will rarely use more than one. The reason is that the files being played must add up to a single complete HTML file (as far as the HTML browser is concerned). In order to play an HTML file, a Sapphire/Web CGI does the following: First, the CGI must find the HTML templates, then the directory is set through the project option, test.HTML Path. Second, the CGI will change its current working directory to the intended directory, read in the HTML template, and print out sections of your template file. Third, the CGI looks for a data site when doing this, the Data Site is represented in the HTML files as:

##Sa_SiteName##
where SiteName is the site's name (as bound to a column in the Object Bind Editor) or a site value for loop constructs or embedded SQL. Each Site Name is processed as it is encountered. If the site is embedded SQL, the SQL might be processed, depending on whether certain projects are set. Embedded SQL sites look like:

##Sa_SQL=select * from authors##
If the site is a Site Name, the CGI will determine the Population Callback to invoke with the data returned by the data object. This may be called multiple times during the playing of the CGI, if the same Site Name appears multiple times in the HTML template. For example in the following example, the Population Callback for "LastName" is invoked 3 times.

The author, ##Sa_LastName##, currently lives in the state of ##Sa_state##. ##Sa_FirstName## ##Sa_LastName## can be reached at ##Sa_phone##. For titles written by ##Sa_LastName click here. ##Sa_HotList##<A HREF="AnchorName" >Title</A>.

When this fragment is being "played", the first fragment, "The Author," is written to standard out. The Population Callback for the site LastName is invoked. This callback may write Ringer to standard out. The next fragment, up to the next site, is written to standard out. Then the next site is processed. You can think of this as substituting data into the sites, because that's what the HTML user will see. The last site, "Hotlist", should be bound as a Hotlist and the Anchor bound as an Activator¯to bring up the titles for that author.

Sapphire/Web allows the developer/user to write the HTML fragment in any authoring tool. As the documents are prepared, users can select data sites via clicking the insert ##Sa_## and expect dynamic population at runtime. The writer/user doesn't need to know database table or column names.

However, the method by which the developer/user names the sites can be used as a design specification to the Sapphire/Web developer. Good design maximizes efficient, on-line document production for the entire enterprise. This is the document-centric concept of HTML, and a fundamental concept of how Sapphire/Web works. One option is to use a source repository. Sapphire/Web provides hooks to these. (See Shell Scripts in the Reference Manual for more information). Also, Sapphire/Web provides some capability to work concurrently on HTML files through its refresh mechanism.

Here is a situation you may encounter. The Sapphire/Web developer completes the application and then goes on to other projects. The original author decides that the code fragment should be reworded as follows:

The author, ##Sa_FirstName## ##Sa_LastName##, currently 
lives in the state of ##Sa_state## and can be reached at 
##Sa_phone##. For titles, click here: 
##Sa_HotList##<A HREF="AnchorName" >
Even after this change the application works seamlessly with no need to design, build, or test. At the next click every one in the enterprise sees the new format¯ Sapphire/Web gives you dynamic, live documents.

The above example will look good to the HTML user even if there is only one row or author returned. This will certainly be the case if the original anchor was bound as a HotList with the Primary Key for the Authors Table.

Suppose you wish to duplicate this text for each author returned; i.e., an on-line address book of authors writing for a certain publisher. To accomplish this, insert the indented code lines above (from The author.......... to Name>) between the ##Sa_BeginLoop## and ##Sa_EndLoop## comments. This construct, called a Sapphire/Web loop, has special meaning to the "playing" of HTML files. When a Sapphire/Web CGI sees this construct, it will "play" the fragment between the ##Sa_BeginLoop## and ##Sa_EndLoop## comments repeatedly for each row, as described for normal "playing", until any site in the fragment runs out of rows. Please note that the fragment is "played" once even if no rows were returned.

Sapphire/Web allows you to add your own Population Callbacks. For these calls, you receive a data structure with all the data returned. When your callback is called outside of the loop structure, all the rows are in the data structure. When called within a loop construct, the data structure contains only one row, the current row derived from the current loop counter. When you write a Population Callback, write it to be generic, and the mode will be transparent to your Population Callback.


[Prev] [Next] [Top] [Bottom] [Contents] (4 out of 22)