Click for System Requirements.
loadhtml($htmlfile,@args)
$htmlstring = buildhtml($htmlfile,@args)
AllowEvals(1|0)
cnvt
set_poc($poc_name)
SetListSeperator($separator_string).
The Perl CGI program calls loadhtml when it is ready to generate an HTML page. The 1st argument is the path and file-name of the html template file to be used to generate the page. The remaining arguments are the data values to be substituted in the html page based on special HTML codes within the template page before the final page is displayed. When loadhtml is called, the template html file is loaded and parsed, all argument/parameter substitutions are made, all dynamic html is generated, and the final html is sent to the browser to be displayed. NOTE: It is the calling program's responisibility to print any needed HTML headers BEFORE calling loadhtml.
By default, embedded perl code and variables in HTML templates are not evaluated for security reasons. To enable loadhtml to process these, first call "AllowEvals(1)". To turn back off, call "AllowEvals(0)".
Call "set_poc" at the beginning of your CGI script to set a point-of-contact name to be displayed on any error screens generated by LoadHtml.
By default, any Perl list argements passed to loadhtml, where the corresponding
html code in the template file is not within a "LOOP" or "SELECTLIST" construct,
will print out all values of the list separated by a comma followed by
a space. Call "SetListSeperator" to change this string to something
else. Within the "LOOP" and "SELECTLIST" constructs, html is dynamically
generated for each element within the resulting list.
<HTML>
<BR>Roses are :1, violets are :2.<BR>
</HTML>
The following call to loadhtml would supply the proper values:
loadhtml('/usr/htdocs/myhtml.htm','red','blue');
and would display the following HTML page:
<HTML>
<BR>Roses are red, violets are blue.<BR>
</HTML>
":1" is replaced by the 1st argument after the file-name, and ":2" with the second one.
NOTE: It is now possible to call loadhtml with NAMED parameters as follows:
The above example using Named Parameters:
<HTML>
<BR>Roses are <!:roses>, violets are <!:violets:>blue normally<!:/violets>.<BR>
</HTML>
The following call to loadhtml would supply the proper values:
loadhtml('/usr/htdocs/myhtml.htm', -roses => 'red', -violets => 'blue');
and would display the same results. NOTE: If data is not substituted using named parameters, try enclosing each "-parametername" part in single quotes. Also, the format ":{name}" is used in leau of ":number" in the HTML whenever a value is to be substituted OUTSIDE of a tag OR within a 'value=":{name}"' part of a tag. Otherwise (within tags), just use the format ":name".
NOTE: In the above example, we show "roses" as a single, unmatched tag. "violets" is shown as a matching tag (note the colon before the closeing >). The text in between ("blue normally") is the default text and is shown if the page is not browsed via LoadHtml.
Now, suppose we want the HTML page to function as a stand-alone page without being called by a CGI script, to demo to a customer before writing the script, you could write:
<HTML>
<BR>Roses are <:1:>red<:/1>, violets are <:violets:>blue<:/violets>.<BR>
</HTML>
This would display the same results as the previous example (note the mixing of numbered and named parameters), if the page is loaded stand-alone directly into the browser, but, if called with:
loadhtml('/usr/htdocs/myhtml.htm','here', -violets => 'there');
would produce the following dynamically-generated page:
<HTML>
<BR>Roses are here, violets are there.<BR>
</HTML>
If no default values are desired, the template file could be written as:
<HTML>
<BR>Roses are <!:1>, violets are <!:2>.<BR>
</HTML>
If a different default value is desired, as when the page is loaded
via LoadHtml, but without a value
for that specific argument, the template file could be written as:
<HTML>
<BR>Roses are <:1=pink:>red<:/1>, violets are <:2=violet:>blue<:/2>.<BR>
</HTML>
Now if LoadHtml is called as:
loadhtml('/usr/htdocs/myhtml.htm','scarlet');
The following page would display:
<HTML>
<BR>Roses are scarlet, violets are violet.<BR>
</HTML>
Formatting
LoadHtml also supports the "printf" function familiar to C and Perl programmers for formatting parameter as they are displayed. If this is not sufficient, user-defined formatting functions are also supported. For example, to right-justify numeric parameters, one could use the "printf" formatting characters: "-10.2f" as shown below:
<BR>The results are <!:1%-10.2f%0.00:>0.00<!:/1>
This provides that ":1" will be displayed using "printf" formatting, with defaults of "0.00".
To format currency, one could define a formatting function within the CGI script to place commas every 3 digits, add parenthesis if negative, etc. For example:
sub cashit
{
my ($val) = shift;
my ($iter) = shift;
my ($lastrow) = shift;
$val = sprintf('%.2f',$val);
$val =~ s/(\d)(\d\d\d)$/$1,$2/;
$val =~ s/(\d)(\d\d\d),/$1,$2,/g;
$val = '(' . $val . ')' if ($val =~ s/^\-//);
return ("$val");
}
Then include the following in the HTML template:
$<!:1%&main::cashit% 0:>0<!:/1>
This formats the dollar amount with commas every three digits and adds
parenthesis if negative. Two decimal places are also displayed.
Sometimes, simple parameter substitution is not sufficient. LoadHtml provides several special control structures to handle more complex dynamic HTML generation.
"IF-THEN-ELSE" statement:
Consider the following HTML template file:
<HTML>
<H3>Jim's Joke Page!</H3>
<BR>
<!IF :1 =~ /flowers/i>
<BR>Roses are <!:2>, violets are <!:3>.<BR>
<!ELSE>
<BR>Knock Knock, who's there? <!:2>, <!:2>
who?, <!:3>, that's who!
<!/IF>
</HTML>
This example will generate two different joke-lines, depending on the value passed as argument #1.
loadhtml('/usr/htdocs/myhtml.htm','FLOWERS','red','blue');
will produce:
<HTML>
<H3>Jim's Joke Page!</H3>
<BR>
<BR>Roses are red, violets are blue.
</HTML>
whereas:
loadhtml('/usr/htdocs/myhtml.htm','KNOCK-KNOCKS','Foold','Fooled You!');
will produce:
<HTML>
<H3>Jim's Joke Page!</H3>
<BR>
<BR>Knock Knock, who's there? Foold, Foold who?, Fooled You!, that's
who!
</HTML>
NOTE: The "ELSE" portion is not required.
If one of the parts is desired for a default, the other can be commented
out with HTML comments, for example:
<!IF :1>normal text<!ELSE><!-- special-case text --><!/IF>
If invoked as a stand-alone HTML page or if ":1" is non-null or non-zero, "normal text" will print, otherwise, "special-case text" will print. The HTML comments will be removed automatically for the text, if the corresponding condition evaluates to true.
"LOOP" Statement:
Another, more powerful construct is the "LOOP". A LOOP repeatedly generates its HTML body for each value in a Perl list. The LOOP construct has the following general format:
<!LOOP[loopname] [first..last[|increment]] [list-parm [, listparm...]]>
-body-
<!/LOOP[loopname]>
For example:
<HTML>
<H3>Dallas Cowboy's Star Roster</H3>
<P><TABLE>
<TR><TH>No.</TH><TH>Name</TH><TH>Jersey</TH></TR>
<!LOOP 1, 2>
<TR><TD>:#+1</TD><TD><!:1></TD><TD><!:2></TD></TR>
<!/LOOP>
</TABLE>
</HTML>
If called with:
&loadhtml('/usr/htdocs/myhtml.htm',[
'Troy Ackman','Emmit Smith','Michael Irvin'],[
8,22,88]);
would produce:
<HTML>
<H3>Dallas Cowboy's Star Roster</H3>
<P><TABLE>
<TR><TH>Name</TH><TH>Jersey</TH></TR>
<TR><TD>1</TD><TD>Troy Ackman</TD><TD>8</TD></TR>
<TR><TD>2</TD><TD>Emmit Smith</TD><TD>22</TD></TR>
<TR><TD>3</TD><TD>Michael Irvin</TD><TD>88</TD></TR>
</TABLE>
</HTML>
The values "1, 2" in the "LOOP" statement means that parameters 1 and 2 contain perl list references instead of scaler values. The ":#" represents a special value -- the iteration number of the loop being processed (starting with zero). We use ":#+1" to cause this value to start with one instead of zero). If loops are nested (and thus named, the name can be appended to the ":# variable, ie:
<!LOOP_LOOPNAME 1>
<BR>Now in iteration: :#_LOOPNAME
<!/LOOP_LOOPNAME>
By default, the loop executes with ":#" starting with zero, incrementing
by one and continuing through
the last value of the 1st list parameter specified. This can
be overridden by specifying starting and ending values and optionally,
an increment value. For example:
<!LOOP 10..100|5 1>
<BR>The loop index is now: :#, the list
value is :1.
<!/LOOP>
This would produce 19 lines of output, the value printed for ":#" would be 10, then 15, 20, ...100. The tenth, 15th, 20th, 25th, ... and 100th elements of the list passed as argument 2 to LoadHtml() would be displayed. If that list contained less than 100 elements, empty strings would print for the missing elements. This is also useful to reverse the order of a list, for example:
<!LOOP 20..1|-1>
...
<!/LOOP>
Naming and nesting IF and LOOP constructs.
IF and LOOP constructs can be nested with each other. If nested within the same construct, however, they must be named (in order for the parser to match up the proper closing tags). To name an "IF" or "LOOP" constuct, simply append an alphanumeric string to the keyword, for example:
<!IF2>...<!ELSE2>...<!/IF2>
-or-
<!LOOP_OUTER>...<!/LOOP_OUTER>
The "IF" is named "2", and the "LOOP" "_OUTER".
"SELECTLIST" Statement:
Another compound construct is the "SELECTLIST". It generates an HTML "SELECT" statement using the elements of a Perl list or hash, generating an "OPTION" line for each element in the list or hash. The general format is:
<!SELECTLIST NAME=select_name [VALUE[S]=value_list] [DEFAULT[SEL]=default_value]
[(BYKEY)|BYVALUE] [REVERSE[D]] :list_parameter>
[...HTML to display if page invoked standalone...]
<!/SELECTLIST>
The NAME and any options other than "VALUE" or "DEFAULT" are added to the generated SELECT statement. The "list_parameter" (required), by default, becomes the values for the generated "OPTION" lines. If "list_parameter" is a Perl hash, then the keys of the hash become the arguments for the "VALUE=" part of each OPTION line, and the values become the displayed items in the listbox. The values are then character-sorted by key (BYKEY) unless "BYVALUE" is specified. "REVERSE" reversed the order. If "list_parameter" is a list and a second list is supplied via the "VALUE" option, then the second list becomes the "VALUE=" part of each OPTION line and the "list_parameter" list items are displayed. They are displayed in the order they appear in the list(s), unless "REVERSE" is specified. If no "VALUE" option is given and "list_parameter" is a list, then no "VALUE=" option is generated and the values become both the actual values and the displayed values for the listbox. The DEFAULT option, if specified, is a value which is to be the initially highlighted value in the select-list. If the "MULTIPLE" select option is specified, then the "DEFAULT=" value may be either a scalar or list-reference. Each value in the "DEFAULT" list is matched against the "VALUE" list and those that match are "SELECTED" by default. If "DEFAULTSEL=" is specified, the default list values are compared with the SELECT values instead the "VALUES" values. Note that the resulting selection-list items are sorted in character-sequence order when the list parameter is a hash To get a true numeric sort, one must left-pad the hash keys with spaces. Example:
<!SELECTLIST NAME=id DEFAULT=":1" :2><INPUT NAME=id TYPE=TEXT><!/SELECTLIST>
...
$mydefault = 123;
%idhash = (110 => 'John Smith', 145 => 'Richard
Adams', 123 => 'Mike Cox', 132 => 'Eddy Jones');
&loadhtml('/usr/htdocs/myhtml.htm', $mydefault,
\%idhash);
This would produce the following HTML:
<SELECT NAME=id>
<OPTION VALUE="110">John Smith
<OPTION SELECTED VALUE="123">Mike Cox
<OPTION VALUE="132">Eddy Jones
<OPTION VALUE="145">Richard Adams
</SELECT>
Checkboxes and radio-buttons:
Checkboxes and radio-buttons also require special handling. A default value is specified in the HTML via a parameter. The parameter will be replaced by the word "CHECKED" if it's value matches the value specified for the checkbox or radio-button. for example:
<BR><INPUT TYPE=CHECKBOX NAME="checkit" :1>Check here if True!<BR>
If the value passed to ":1" is "true" in Perl (not zero, empty string, or whitespace), the HTML will be generated with ":1" replaced with the word "CHECKED", otherwise, the ":1" it will be removed. NOTE: If the word "CHECKED" is already in the HTML, it will be removed if the value for ":1" is false, but will remain if no argument is defined for ":1".
<INPUT TYPE=RADIO NAME="topings" VALUE="meat" :1>Give me Meat and
Cheese
<INPUT TYPE=RADIO NAME="topings" VALUE="veggies" :1>Give me Veggies,
please
If the argument passed to ":1" is equal 'meat' or 'veggies', then the
corresponding radio-button will be marked "CHECKED", otherwise, neither
will be checked.
"INCLUDE" statement:
Additional HTML files can be loaded and processed within an HTML file via the "INCLUDE" statement. All files loaded via the "INCLUDE" statement are also parsed and modified the same way the initial HTML file is. The include file can be specified as either a server file-name or a url. Examples:
<!INCLUDE /user/htdocs
<!INCLUDE http://domain/path/myhtml.htm>
Providing default values for form items.
LoadHtml provides special ways to assign default values to HTML "INPUT" statements. Consider the following for putting a default value into a TEXT field:
<INPUT NAME=name TYPE=TEXT VALUE=":1">
This will work, but LoadHtml provides a better way. If done this way and the form is invoked stand-alone, the input box will show a literal ":1", which is probably not desired for demos. The preferred way is:
<INPUT NAME=name TYPE=TEXT VALUE="standalone-default" :1=default>
This provides a value "standalone-default", if the page is invoked as stand-alone HTML and a value of "default", if no argument or "undef" is passed for the corresponding argument. If the "=default" string is omitted, the box will show as empty, if no argument is passed for ":1". NOTE: If an empty string is passed as an argument, the box will be empty regardless of any default values specified! This option also applies to "HIDDEN" input fields.
<SELECT NAME=myselect :1>...</SELECT>
This permits the default (initially highlighted) value of the SELECT statement to be specified by argument 1.
<TEXTAREA... :1=default>stand-alone default</TEXTAREA>
This works similar to the "<INPUT TYPE=TEXT...>" input field described
previously.
Embedding Perl variables:
If "AllowEvals(1)" is called before calling "loadhtml", then any embedded Perl variables of the format: ":$scaler or :$array[index] or :$hash{index} or :$package::variable will be replaced by it's value current at the time LoadHtml is called.
Embedding Perl code (the "EVAL" Statement):
If "AllowEvals(1)" is called before calling "loadhtml", then any Perl code between the tag: "<!EVAL.../EVAL>" will be evaluated and any returned results will replace the EVAL tag. Consider the following example:
<!EVAL
my (@t) = localtime(time);
return ($t[3] . '-' . (qw(JAN FEB MAR APR MAY JUN
JUL AUG SEP OCT NOV DEC))[$t[4]] . '-' . $t[5] . '.');
/EVAL>
This tiny Perl program calls Perl's "localtime" function, and returns the current date with the month formated into it's proper three-character abbreviation. The more complicated example below generates a dynamic url link:
<!EVAL
my ($homepage) = ":0";
$homepage =~ s/userpage/pp:4/;
if (-e "$homepage")
{
$homepage = 'http://myhost.domain.com/cgi-bin/loadtext.pl?link='
. $homepage . '&args=:1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16,:17,:18,:19,:20,:21,:22';
return ('<CENTER><BR><A HREF='
. $homepage . '>Go to my Personal Homepage</A></CENTER><BR><HR
SIZE=5>');
}
/EVAL>
Note that parameter substitutions take place within this code.
Also note the use of ">" in lieu of the ">" symbol. This is
required to prevent the HTML processor from closing the "<!EVAL" tag
before the end of the "EVAL" code! The special parameter ":0" contains
the name of the html template file.
Embedding hash-definitions within HTML pages:
Hash tables can now be defined within an HTML page for creating lookup tables, etc. To create a hash table, use the " tag. For example:
<!HASH attbdescs>
'any' => 'Any attribute',
'di' => 'Direct/Indirect',
'dgr' => 'Education (Degree)',
'ins' => 'Education (Institution)',
'maj' => 'Education (Major)',
'exl' => 'Experience (LM)',
'ex' => 'Experience (Total)',
'flv' => 'Foreign Language',
'flw' => 'Foreign Language',
'fpt' => 'Full/Part Time',
'ou' => 'Organization',
'pos' => 'Title',
'sg' => 'Salary Grade',
'sc' => 'Security Clearance',
'sk' => 'Skills and Knowledge',
'tr' => 'Training'
<!/HASH attbdescs>
This defines a lookup table for several codes and gives each a description. The hash can be any valid Perl hash-definition. The hash will be referred to within the HTML by the name "attbdescs". To cause a hash's value to be displayed, use its name in the special tag in the format:
<!%hashname{key}default>
For example to display the following tag:
<!%attbdescs{pos}>
would be replaced with "Title". The real use for this is specifying the key dynamically, ie:
<!%attbdescs{:1}-NO SUCH VALUE!->
The result depends on the value of ":1". If the value of ":1" does not match any of the key values, then "-NO SUCH VALUE!-> is displayed.
If the template page is also being used stand-alone, the entire hash definition (between "<!HASH...>" and "<!/HASH>) can be enclosed as a comment ("<!-- ... -->").
2) Perl, v. 5.003 or better.
3) Perl's "LWP" module and required prerequesites: MIME-Base64
(MIME), HTML-Parser (HTML), libnet (Net), MD5, and Data-Dumper (Data).
All of these are available for download from CPAN.