Using 4D HTML Tags in Version 6.7
By Hugo Fournier, 4D, Inc. Technical Support.
Technical Note 01-1
Technical Notes for Technical Notes for 01-01 January 2001
Introduction
This technical note describes a way of implementing web serving for semi-dynamic pages. It takes advantage of new Web server features of version 6.7. To illustrate those new features and their added convenience, this technical note compares the technology used in version 6.5 (and described in TN 36-00) to this approach.
A Review of TN 00-36
In that technical note, the point was to demonstrate the publication of a data-driven database. The difficulty of that implementation was due to the requirement that the information published on the web site must be updated automatically whenever the data in the database changed. In other words, if some chapters were added, they would appear when requested with no modifications in:
4D code,
the HTML template used to publish the document.
To achieve that, it was necessary to:
1. Define the basic HTML template document to use
2. In that document, define the target strings that will be replaced by actual data
3. Process, in 4D, the contents of the HTML source so that the number of insertion strings matches the data in the database.
4. Still in 4D, replace each of those strings with actual data.
5. Send the file.
Although that implementation remained simple, it involved a fair amount of string management/replacement since the final code that eventually was sent to the browser was going through several stages of processing. With version 6.7, implementing exactly the same information is much simpler because of important additions to 4D HTML tags.
Principle
As said earlier, this technical note takes advantage of HTML tags that were not available in version 6.5. Because of that, the original technique, which was based on fully dynamic pages, was switched to publishing semi-dynamic pages. You should not consider as mandatory to use semi-dynamic pages (Blobs that are sent with the Text/HTML type are parsed as .shtm files would). In the present technical note, the choice was made to use a source HTML document placed in the Web Folder folder. That document is parsed and modified by 4D, based on the 4D Tags left in it.
The enhancement that makes implementing a data-driven page easy (read "much easier") is the presence of the <!--4DLOOP [MyTable]/<!--4DENDLOOP
tags. These Tags allow you to repeat the HTML code placed between them. When used jointly with the <!--4DHTMLVAR MyVar
or <!--4DVAR MyVar
tags, it allows you to insert data based on your current selection. This is used to replace the heavy HTML handling that was used in TN 36-00. In addition to those tags, the <!--4DSCRIPT/MyMethod
tag is used to execute 4D methods at several stages of the parsing of the HTML document.
Getting Started
If we go back to the original document used in TN 36-00, it looks as follows:
There were two types of placeholder strings:
Chapter_Target
That string was to be replaced by chapter titles. They would appear with a link on them. Clicking that link would search the related table so that the contents of that chapter appears in the right hand side of the page.
Body1_Target and Body2_Target
These strings were to be replaced by chapter subtitles and contents.
Replacing the Chapter_Target String
In the previous technical note, this was performed by duplicating the target as many times as there were chapters in the [Chapters] table and then by replacing those new targets by actual data. This can typically be done by using the following sequence:
You will certainly notice the presence of a 4DSCRIPT tag along with a 4DVAR tag. The 4DSCRIPT tag is designed to trigger the execution of the Set_Space method. It is executed once for each record of the [Chapters] table. This method contains the following code:
NoSpace:=Replace string([Chapters]Title;" ";"%20")
By triggering that method each time the loop is run through, a process variable is set that contains the current chapter title with spaces replaced by "%20". This is necessary since the chapter title has to be input as a parameter to the method called by the 4DACTION tag. In URLs, space characters have to be replaced by "%20", your browser may or may not do it (Have you had any problems trying to get consistent behaviors between different browsers lately?). After that variable is set, it is retrieved and inserted in the HTML code by the <!--4DHTMLVAR NoSpace. The insertion of the chapter title and the IP Address is performed by the tags <!--4DVAR [Chapters]Title
and <!--4DVAR [Templates]IP_Address
.
This simple HTML code and the method it calls replace all the HTML handling that was performed in the earlier technical note for replacing the Chapter_Target.
Replacing the Body1_Target and Body2_Target Strings
In the previous technote, these strings were initially duplicated to provide as many target strings as there were records for a specific chapter. Here it becomes much simpler to implement the replacement mechanism:
As with the Chapter_Target String, a 4DLOOP is used to repeat the HTML contents for each record. This, again, elminates the need for creating intermediate strings. You will also notice the call to the NO_CRs method. This method sets the value for the variable NoCRs. This variable is used to stored the contents of the paragraph field where the carriage returns have been replaced by "</p><p>". This variable is later used by the <!--4DHTMLVAR NoCRs tag. This allows the display of paragraphs as they would appear in the text field.
Once all the target strings were replaced by 4D tags, there are two aspects to manage, the selection management and the use of a disk file as the source SHTML file.
Managing the selection
The selection of records is managed by the Welcome method. It basically addresses two cases:
Is it the first time the connection is established ($1 is undefined)
A $1 parameter is passed (connection originating from a link)
ALL RECORDS([Templates])
If (Type($1)=5)
`Is that variable undefined?
ALL RECORDS([Chapters])
ORDER BY([Chapters]Sequence_ID;>)
RELATE MANY([Chapters]Title)
ORDER BY([Paragraphs]Sequence_ID;>)
ALL RECORDS([Templates])<html>
Else
$1:=Replace string($1;"/";"")
QUERY([Paragraphs];[Paragraphs]Title=$1)
ORDER BY([Paragraphs]Sequence_ID;>)
ALL RECORDS([Chapters])
End if
SEND HTML FILE("static.shtml")
Using an HTML source file for the parsing
In the previous technical note, the HTML contents were stored in a text field in the [Templates] table. This is now performed by parsing an SHTML file (static.shtml) stored in a folder named "Web Folder". That folder is also defined as the HTML root in the Database Properties so that the path to the HTML source file is a relative path. The code statement that sends the file and initiate the parsing is located at the end of the Welcome method:
SEND HTML FILE("static.shtml")
Summary
This technical note describes a simple way of serving semi-dynamic pages using version 6.7. The sample database actually publishes the exact same HTML contents as the database described in TN 00-36, however its implementation is much simpler due to extensive use of version 6.7 4D HTML tags.