LoadHtml - Dynamic HTML Generation Library, by Jim Turner. LoadHtml is a Perl library to enable Perl CGI programs to dynamically generate HTML pages from HTML page templates. LoadHtml includes the following special features: I) Special HTML control statements (IF-THEN-ELSE, LOOP, INCLUDE, SELECTLIST, etc.)! II) HTML templates can be valid stand-alone HTML pages (with default values) for rapid prototyping. III) Perl code and variables can be optionally embedded or prohibited for security reasons on a page-by-page basis. IV) HTML pages can be generated and later displayed or saved using the "buildhtml" function. V) Easy table and select construct creation using Perl lists and hashes. LoadHtml is written completely in Perl, a modern, high-performance scripting language. CGI web applications are completely portable across all platforms which support Perl and CGI, including Unix and Windows. Click for System Requirements. I) Overview / User-callable Functions. The following functions are user-callable: 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. II) Parameter Substitution and Special HTML Control Statements. loadhtml is called with the 1st argument being the filename of the HTML template file to load. Each subsequent argument corresponds to a data-value to be added to the HTML via parameter substitution. The simplest parameter substitution is accomplished by placing the argument number preceeded by a colon in the desired location for the corresponding data-value argument in the HTML template file. For example, if an HTML template file named "myhtml.htm" in directory "/usr/htdocs/" looked like the following:
Roses are :1, violets are :2.
The following call to loadhtml would supply the proper values: loadhtml('/usr/htdocs/myhtml.htm','red','blue'); and would display the following HTML page:
Roses are red, violets are blue.
":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:
Roses are , violets are blue normally.
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:
Roses are <:1:>red<:/1>, violets are <:violets:>blue<:/violets>.
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:
Roses are here, violets are there.
If no default values are desired, the template file could be written as:
Roses are , violets are .
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:
Roses are <:1=pink:>red<:/1>, violets are <:2=violet:>blue<:/2>.
Now if LoadHtml is called as: loadhtml('/usr/htdocs/myhtml.htm','scarlet'); The following page would display:
Roses are scarlet, violets are violet.
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:
The results are 0.00 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: $0 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:

Jim's Joke Page!



Roses are , violets are .

Knock Knock, who's there? , who?, , that's who! 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:

Jim's Joke Page!



Roses are red, violets are blue. whereas: loadhtml('/usr/htdocs/myhtml.htm','KNOCK-KNOCKS','Foold','Fooled You!'); will produce:

Jim's Joke Page!



Knock Knock, who's there? Foold, Foold who?, Fooled You!, that's who! 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: normal text 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: -body- For example:

Dallas Cowboy's Star Roster

No.NameJersey
:#+1
If called with: &loadhtml('/usr/htdocs/myhtml.htm',[ 'Troy Ackman','Emmit Smith','Michael Irvin'],[ 8,22,88]); would produce:

Dallas Cowboy's Star Roster

NameJersey
1Troy Ackman8
2Emmit Smith22
3Michael Irvin88
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:
Now in iteration: :#_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:
The loop index is now: :#, the list value is :1. 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: ... 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: ...... -or- ... 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: [...HTML to display if page invoked standalone...] 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: ... $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: 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:
Check here if True!
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". Give me Meat and Cheese 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: 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: 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: 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. This permits the default (initially highlighted) value of the SELECT statement to be specified by argument 1. stand-alone default This works similar to the "" 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: "" will be evaluated and any returned results will replace the EVAL tag. Consider the following example: 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: 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 " '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' 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: For example to display the following tag: would be replaced with "Title". The real use for this is specifying the key dynamically, ie: 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 "" and ") can be enclosed as a comment (""). V). Minimum System Requirements: 1) Any system supporting Perl and CGI. 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. *NOTE: You can use it WITHOUT LWP, et. al. if you comment out the references to LWP::Simple::Get and use unix file-paths instead of urls.