Useful Components for CGI applications

Gabriel Corneanu

Description

This is a package for developing CGI applications using Delphi (C++ Builder). One big difference (I would call it advantage) between these components and other packages is that they are used in extension to the standard Borland components for CGI applications.
Do you need to generate form elements in Delphi? Do you want to include live images in your pages? Try this!

History

Version 2.5

Version 2.3

Version 2.2

Version 2.1

Version 2.0

Version 1.8

Version 1.5

Version 1.0

Custom producers

The base component is HTMLProducer. It is a direct descendant of PageProducer, with some enhancements. For every custom tag (or transparent, <#tagname>) found in the HTML source, it tries to find one producer that handles the tag. This means the programmer doesn’t have to write code for OnHTMLTag event. CustomTags is the property for matching between tags and producers. The special property editor provided helps you to edit at design time.
The other producers are all descendents of one ancestor, HTMLBase (abstract), which is also a CustomProducer.
Previous versions (before 2.5) had a hard relationship between HTMLProducer and the descendants of HTMLBase producers, and you couldn't use standard producers (like TableProducer) in response to a custom tag. The new approach removed this limitation. When you open a project buid with old components, you will get some errors about missing properties. Ignore all of them and then use the CustomTags property editor to remap the producers with custom tags.

The HTMLBase introduce one common property:

The producers are:

Custom Fields

The purpose of this group is to help generate HTML form elements to be used with a DataSetTableProducer. This is a very useful component, but unfortunately it was no way (until now) to include (for example) another column for making a selection (check or radio), or an edit field for each row (now even a Image!). And I couldn’t live without it.
The solution is to add fake fields into the dataset and let them generate the right HTML! You can enjoy the editor provided with Delphi, and preview the result (not applicable to Images)! So open the fields editor for a table and click new field. Choose a HTML... field, and add a column to the TableProducer, linked to this field.
Warning: the classic (inherited) properties have noeffect on these fields. They are calculated fields. Don’t use them for other purposes (like normal editing).

Most of the fields have 2 base properties:

Field list:

HTMLMultiPage

A single component designed to help present the content of a dataset (possible search results) in a multi page manner (every page can have a variable number of rows/columns). It is also a custom producer described in the beginning, so you can include it in another page generated by an HTMLProducer. Specific properties and events are:

This component is not finalized (it doesn’t mean that the others are prefect, but here it is space for more work). Any ideas/suggestions are welcome.

HTMLFields

This is a description of the format used by some properties (HTMLValueFields, HTMLVisibleFields, HTMLNameFields...). Usually the parameters for the tags are combinations depending on some logic. The rule is simple: any text surrounded by "%" is considered to be the name of a field and replaced by the value of that field. You can use any combination, like "N_%ID1%_%ID2%". If no "%" is found, the output is constant. The "%%" sequence is replaced with "%".

Example: if you have a combo with some persons, you may want to use some id as the value (the key of a table), and as text a combination of first name and last name, like <OPTION value="123">JOHN DOE<OPTION>. For this, you can set HTMLNameFields="%ID%" and HTMLValueFields="%F_Name% %L_Name%". For radio elements: they are grouped by name, so usually it is a constant, but the value is a key identifying the row. For checkbox elements, usually it is the opposite: the name depends on a key, and the value is a constant like "on" or "true". By default, the property editors suggest a combination of HTML FieldName and another field.
For HTMLKeyFields, this is not applicable: it expects to find only a list of existing fields, and you can choose from existing indexes (primary or unique). It is intended for internal use (see Images). The same for HTMLImageField; it only wants a name of a field.

Images

Here I’m trying to describe what’s going on with (live) images. As you know, an image is not part of the HTML document; it is only a tag containing a link to the actual images. Let’s suppose you have images in a database, and want to output them in HTML. You can save the image to a file, and generate a link to it. Outside of a good garbage collection mechanism for deleting old files, this is not very nice. It is the same problem in JSP, or ASP. The Web server environment must provide some help.

I didn’t want to use other storage for the files. And I used another solution: to generate a link back to the same CGI application. Of course, the next call should return the actual image, not the default content. If you are carefully, you can do it in Delphi. But I have already built some support for it, so give it a chance.

How it works: for every image, it is generated a link to the same CGI, but a different pathinfo. Don’t worry; everything is done internal, and only at runtime. You only have to write code in the OnGetImageAction event. For this, you can use some helper functions (declared in HTMLCommon):

All of them build an image from a form, from a bitmap, from a WinControl or from a Field (it must be a Blob field, and contain a valid image) and give it as response. As you also know, the usual format for HTML images is jpeg, so all the images are sent in jpeg format (this is because Delphi has support for it). But if the field contains a valid GIF image (or a JPEG image), it is left untouched. I am only looking for some header values, so please report any error.

Now if you have a simple HTML page, it is ok. But if you have dynamic pages, like the content of a table (with images), this is not enough. You can’t know in the event what image to deliver. The only help is if you use some parameters as part of the request (included in the image source link). If we are sending the key of the row, than we can handle it.

This is the idea. It is not that hard, but it requires some work. So I tried to do as much as possible. I think that in 95% you only have to specify the right properties: keys, image table and field (I’m trying to build a query, so I need the field name, table name and the row key). In 50% I can fill some of these automatically: if using a TTable, the HTMLImageTable is automatically filled with the TableName property and the indexes are scanned for a primary key (or a unique key), and assigned to HTMLKeyFields property; if it finds a TGraphicField, the HTMLImageField is also filled (usually they are just blob fields, so you have to fill it). If using a TQuery and you are including the image field in result, it might help to find the table from the Origin property. There are registered property editors for these properties, but usually you shouldn’t include the image field in the dataset used for generating the table (we don’t need the image field at this time); in this case you won’t find the field in the list.

To resume: if the HTMLKeyFields are set, the result is something like <IMG SRC="sameCGI/pathinfo?key1=val1&key2=val2...">. The HTMLImageTable and HTMLImageField are used at the next call (if using internal handling). You can specify extra parameters through HTMLSrcParams, but only if not using internal handling.

Other things: the link to the CGI is well formed, even if you are inside some other path. Even more, it is a relative link: try /path/Project1.cgi and /path/Project1.cgi/, and look at the HTML source!

I hope I didn’t forget any important thing. I think that the samples included are quite useful.

Enhacements

There are several property editors, and a special catogory for all the specific properties. Right click in the Object Inspector and choose arrange/by category.

Known Issues

Gabriel Corneanu

Email: gabrielcorneanu@yahoo.com