|
|
| #include <stdio.h>
|
| #include <stdlib.h>
|
| #include <dcmicro/htmlpp/htmlpp.h>
|
|
|
|
|
| // Load the specified document template into memory, substituting "$"
|
| // macros with their form/calculated values.
|
| void LoadTemplate( const String& document,
|
| htmlContainer& page,
|
| htmlServer& server,
|
| CLinkedList& object_list )
|
| {
|
| FILE * file ;
|
| char buffer[ 8096 ] ;
|
| String filename ;
|
| String raw ;
|
| String converted ;
|
| String token ;
|
| String field ;
|
| String value ;
|
| int pos ;
|
| Boolean perform_substitution ;
|
| Boolean object_substitution ;
|
|
|
| // temporarily convert document name to uppercase for easy comparison
|
| raw = document ;
|
| raw.ToUpper() ;
|
|
|
| filename = document ;
|
| file = fopen( (char *) filename, "rt" ) ;
|
| if ( file != (FILE *) NULL )
|
| {
|
| // loop for all lines in the file
|
| while ( fgets( buffer, sizeof(buffer), file ) != NULL )
|
| {
|
| raw = buffer ;
|
| converted = "" ;
|
|
|
| while ( ( pos = raw.HasSubstring( "$" ) ) != String::NO_SUBSTRING )
|
| {
|
| String temp = raw.Left( pos ) ;
|
| converted += temp ;
|
| raw -= temp ;
|
|
|
| // look for end of token; first non-alpha or
|
| // non-digit character, or end of string
|
| for ( pos = 1 ; pos < raw.GetLength() ; pos++ )
|
| {
|
| if ( !( isalpha(raw[pos])
|
| || isdigit(raw[pos])
|
| || raw[pos]=='_') )
|
| {
|
| // found next character past end of token
|
| break ;
|
| }
|
| }
|
|
|
| token = raw.Left( pos ) ;
|
| raw -= token ;
|
|
|
| perform_substitution = FALSE ;
|
| object_substitution = FALSE ;
|
| token -= "$" ; // strip off leading $ character
|
|
|
| String temp_token = token ;
|
| temp_token.ToUpper() ;
|
|
|
| // First, check to see if the field appears as a CGI
|
| // name/value pair. If so, use it's value for the
|
| // substitution.
|
| Boolean good_data = server.Enumerate( field, value, TRUE ) ;
|
| while ( good_data )
|
| {
|
| field.ToUpper() ;
|
| if ( field == temp_token )
|
| {
|
| perform_substitution = TRUE ;
|
| break ;
|
| }
|
| good_data = server.Enumerate( field, value ) ;
|
| }
|
|
|
| // The field is not a CGI name/value pair, so
|
| // search the object_list
|
| if ( ! perform_substitution )
|
| {
|
| CListItem FAR * item ;
|
| PObjectDef object ;
|
|
|
| item = object_list.First() ;
|
| while ( item )
|
| {
|
| object = (PObjectDef) item->Item_Data ;
|
| object->name.ToUpper() ;
|
|
|
| // Bingo -- insert the appropriate object
|
| if ( object->name == temp_token )
|
| {
|
| object_substitution = TRUE ;
|
| page << htmlLiteral( converted ) ;
|
| converted = "" ;
|
| page << *object->element_ptr ;
|
| break ;
|
| }
|
|
|
| item = object_list.Next( item ) ;
|
| }
|
| }
|
|
|
| // If token is a form field
|
| if ( perform_substitution )
|
| {
|
| value = server( token ) ;
|
| value.RTrim() ;
|
|
|
| converted += value ;
|
| }
|
| else if ( ! object_substitution )
|
| {
|
| // put raw token back into output string
|
| converted += "$" + token ;
|
| }
|
| }
|
|
|
| // append any remaining raw data
|
| converted += raw ;
|
| page << htmlLiteral( converted ) ;
|
| }
|
|
|
| fclose( file ) ;
|
| }
|
| else
|
| {
|
| htmlContainer error_page ;
|
| error_page << htmlBreak()
|
| << "Unable to open document template file: "
|
| << htmlText(filename)
|
| << htmlBreak() ;
|
| page << error_page ;
|
| }
|
| }
|
|
|
| int main( void )
|
| {
|
| htmlCgi server( cin ) ;
|
| htmlPage page ;
|
|
|
| CLinkedList object_list ;
|
|
|
| // Create an object that represents the contents to
|
| // be included in the template document. This could be
|
| // as complex as you like, including entire tables, text,
|
| // or any other document.
|
| htmlContainer msg ;
|
| msg << htmlBold( "This is the substituted message" ) ;
|
|
|
| // Create an object that will replace the
|
| // "$Message" string in the document template file.
|
| PObjectDef object_ptr = new ObjectDef ;
|
| if ( object_ptr )
|
| {
|
| object_ptr->name = "Message" ;
|
| object_ptr->element_ptr = &msg ;
|
| object_list.Add( new CListItem( (DWord) object_ptr ) ) ;
|
| }
|
|
|
| // Load the HTML document template, specifying
|
| // the list of objects that are available for
|
| // substitution. This will replace any occurance
|
| // of "$Message" in the template with the msg object.
|
| htmlContainer dynamic_doc ;
|
| LoadTemplate( error_page, dynamic_doc,
|
| server, object_list ) ;
|
|
|
| // Output the new dymanically created page
|
| page << dynamic_doc ;
|
| server << page ;
|
| return 0 ;
|
| }
|
|
|
| |