Messages is finally above the 1.0 release number and deservedly so. Using the single %messages.cgi script, you can now do the following: 1. Display news headlines with a built-in commenting system. 2. Run an open discussion forum. 3. Run an open classifieds section. 4. Create, edit, or delete any set of messages (news, forum, classified, other) using an encrypted login system which uses a session ID to timeout administration functions after a specified amount of time. How does it do this? Messages primarily accepts three variables to determine what to do next. You pass the variables actionType, messageType, and messageID via CGI. Following are examples of the types of values these variables may hold: -actionType create-form display a message creation form create create a new message comment create a comment, using the mother message's messageID as the comment's messageType display display messages search search messages for a keyword display-comments display the comments that have been made on a message edit-form return the contents of a message in a form for editing the message edit edit a message delete delete a message display-login display the form for logging in to use administration functions login login to use administration functions -messageType news forum classified other (whatever naming convention you choose) 20010420123456 (the messageID of a parent message, used for comment messages) -messageID 20010420123456 (a string of numbers based on the date and time of creation, also used for naming the XML file which contains the message) Messages also passes the sessionID variable during administration functions. The sessionID is also a string of numbers based on the date and time of sessionID creation or update. Following are the improvements for this version: 1. Added subroutines which removes displaying redundant search forms and message creation buttons after a search. 2. Added a classified advertising system, which is essentially a forum system without the commenting system. 3. Removed some more redundant code. Plans for future versions: 1. Slim down the code as much as possible. 2. Replace encryption system with a new one. 3. Add commenting support to administration functions. 4. Change all forms from GET to POST (currently using GET for troubleshooting purposes.) As always, your comments are greatly appreciated (and even heeded.) The script follows. -Ryan #!rebol -cs REBOL [ Title: "Messages" Date: 20-Apr-2001 Version: 1.0.5 File: %messages.cgi Home: http://www.rebolrepublic.org Author: "Ryan C. Christiansen" Email: [EMAIL PROTECTED] Rights: "Copyright (C) Ryan C. Christiansen 1999-2001" Purpose: { Create, display, edit, and delete messages using a standard XML storage format and CSS2-reference <DIV> tags for display. The script is dependent on the use of .css stylesheets for separate messageTypes. } Comment: { This file %messages.cgi is a single engine for creating, displaying, editing, and deleting messages. For displaying, editing, and deleting messages, %messages.cgi must receive the following variables as CGI input: actionType, messageType, and messageID. For creating messages, %messages.cgi must receive a REBOL e-mail object! as input or the following variables as CGI input: actionType, messageType, subject, author, and content. During message creation, %messages.cgi creates the following variables: date and messageID. } History: [ 0.0.9 [4-Jan-2001 "Created %std_msg_func_lib.r based on previous work." "Ryan"] 0.1.1 [5-Jan-2001 "Added 'display-markup object! functions and changed file name to %standard-message-function-library.r" "Ryan"] 0.1.2 [8-Jan-2001 "Fixed 'read-message-directory to output file names including path to directory defined by messageType." "Ryan"] 0.2.1 [9-Jan-2001 "Corrected target 'word in 'write-xml-message. Added 'create-message object! functions. Corrected 'display-markup to output string! datatype instead of block! datatype. Negated use of 'message-request-data target variable in 'read-directory-messages. Added 'get-messages-for-display object! functions." "Ryan"] 0.2.3 [10-Jan-2001 "Added 'display-messages function, the top-level function for displaying messages. Pared down usage in 'Example portion of header to include only top-most functions. Removed /html-output function from 'get-messages-for-display object! and removed /html function from 'display-markup object!" "Ryan"] 0.2.4 [11-Jan-2001 "Changed the order of values (switched 'author' and 'subject') for the XML grammar in all functions. Changed the 'either switch in 'display-messages from 'none to the string! datatype 'none'." "Ryan"] 0.2.5 [8-Feb-2001 "Removed incorrect class/id combinations from CSS font designations. Changed 'display-markup and 'display-messages to markup content using only CSS class designations instead of class/id combinations." "Ryan"] 0.2.7 [18-Feb-2001 "Added routine to 'display-messages function which will display all messages in a directory minus the content value. The index option is called by sending 'index' as the 'messageID value to 'display-messages." "Ryan"] 0.3.7 [28-Mar-2001 "Changed name of script to %messages.cgi. Changed e-mail address in header. Updated Comment and Example field in header. Changed 'display-markup to markup messages using <div> tags instead of <font> tags. Changed 'display-markup from a function to an object which includes 'for-reading object including 'with-reference (display messageID and messageType) and 'without-reference functions, and also 'for-editing object with 'with-reference function to display a message or messages for editing, including <FORM> and <INPUT> tags. Added 'edit-message function for editing messages. Added 'edited-from-cgi function to 'decode-to-object object! Added 'delete-message function. Added 'message-action-cgi uber-function." "Ryan"] 0.5.0 [29-Mar-2001 "Added return display for delete, create, and edit switches in 'message-action-cgi. Changed 'append to 'insert in 'read-directory-messages function, which will make newest messages display first. Changed radio button value for edit/delete choice from 'choice' to 'actionType'. Fixed the way 'for-editing object functions display form values and form targets. Added form for creating new messages to 'for-editing object functions. Added 'create-form' action type to switch in 'message-action-cgi function. Added 'display-create-form function to display message creation form. Added Bohdan Lechnowsky's %encrypt.r functions. Created 'encrypt-logins function for creating %.bin files containing usernames and passwords. Added 'display-login-form function to display login form. Added 'sessionID check to all administration functions including delete, edit, display-admin, create, and create-form. Added 'sessionID variables to form output in all admin forms. Added sort/reverse statement in 'read-dir ectory-messages function in an attempt to make the newest messages display first. Added if error? try statement to program section script which will default to displaying messages in the absence of cgi input data." "Ryan"] 0.5.1 [30-Mar-2001 "Changed sort/reverse statement in 'read-directory-messages function so that it sorts the 'message-directory block instead of the 'message-block block." "Ryan"] 0.5.6 [4-Apr-2001 "Removed HTML headers from 'display-create-form and 'display-login-form. Removed 'without-reference function in 'display-messages/for-reading object!, making 'display-messages/for-reading a function replacing the 'with-reference function. Made 'display-messages/for-editing a function replacing the 'with-reference function within the 'display-messages/for-editing object! All messages will display references. Changed 'display-admin' switch to 'edit-form' in 'message-action-cgi function. Added parse statement to display 'messageID and 'messageType in 'display-messages/for-editing function." "Ryan"] 0.6.0 [5-Apr-2001 "Added 'display-comments' switch to 'message-action-cgi, including 'reverse-input function which will make the messageID the messageType for comment viewing and posting. Added post/view comments link to 'display-messages/for-editing function. Added error correction to stylesheet loading, making it load %comments.css on error (expecting an error when the messageType is messageID after the 'reverse-input operation. Added 'display-comment-form function." "Ryan"] 0.6.6 [6-Apr-2001 "Added 'post-comment-input object to 'comment' switch, including 'parent-messageID value in 'comment' switch and 'display-comment-form function, allowing a comment's parent to be displayed after commenting, eliminating an error. Made 'display-messages/for-reading function an object! containing functions 'for-commenting and 'no-commenting. Updated 'message-action-cgi switch statements for the change. Added 'parent-message-input object and 'post-comment-reverse-input object to 'comment' switch for displaying original message and proper comment input form after comment creation. Added <DIV> tag to post/view comments link. Added post/view comments links to 'display-messages/for-editing function. Added 'display-comments-edit' switch to 'message-action-cgi function." "Ryan"] 0.7.4 [11-Apr-2001 "Added 'message-block return statement to 'read-directory-messages function and moved 'sort/reverse statement to sort 'message-block instead of 'message-directory. Added error-checking to 'display' switch in 'message-action-cgi. Added 'make decimal! statement to 'login' switch in 'message-action-cgi. Created 'check-sessionID function to replace redundant code in 'message-action-cgi. Added 'sessionID-timeout value in configuration section. Changed 'Edit' and 'Delete' and 'Create New!' options in 'display-messages/for-editing function to be more descriptive. Added 'search-messages function. Added 'search' switch to 'message-action-cgi. Added search form to all 'display-messages object! output." "Ryan"] 0.7.5 [12-Apr-2001 "Moved 'message-block return statement in 'search-messages function. Removed 'search' switch debugging in 'message-action-cgi." "Ryan"] 0.8.1 [18-Apr-2001 "Changed 'insert to 'append in 'read-directory-messages function. Added 'display-search-form function to replace redundant code in 'display-messages object! Added 'display-create-button function to replace redundant code in 'display-messages/for-editing function. Added 'display-edit-message-button function to replace redundant code in 'display-messages/for-editing function. Added 'display-delete-message-button function to replace redundant code in 'display-messages/for-editing function. Added 'display-comments-link function to replace redundant code in 'display-messages object!" "Ryan"] 0.8.2 [19-Apr-2001 "Added 'display-comments-edit-link function to replace redundant code in 'display-messages/for-editing function." "Ryan"] 0.9.4 [20-Apr-2001 "Added 'return-div-text function to replace redundant code in 'display-messages object! Added 'return-messageID function to replace redundant code in 'display-messages object! Added 'return-messageType function to replace redundant code in 'display-messages object! Added 'display-messages/forum-style function for using %messages.cgi to run a forum. Added 'display-create-button-forum function for creating new messages in 'display-messages/forum-style function. Added 'create-form-forum' switch to 'message-action-cgi function. Added 'display-create-form-forum function for displaying a message creation form in a forum environment. Added 'create-forum' switch to 'message-action-cgi function for creating new messages in a forum environment. Added 'display-comments-forum-link function for using the commenting system within a forum environment. Added 'display-comments-forum' switch to 'message-action-cgi function for using the commenting system within a forum environment. Added 'display-com ments-form-forum function for displaying a commenting system form within a forum environment. Added 'comment-forum' switch to 'message-action-cgi for creating comments within a forum environment. Added 'display-search-form-forum function to allow searches within a forum environment. Added 'search-forum' switch to 'message-action-cgi function to return forum-style message display after a search." "Ryan"] 1.0.5 [23-Apr-2001 "Made all 'display-messages object! functions into object! datatypes including 'with-search-form and 'without-search-form sub-functions. Added /with-search-form and /without-search-form paths to switch statements in 'message-action-cgi function. Removed 'display-create-button-forum function from 'display-messages/forum-style/without-search-form function and renamed 'display-messages/forum-style/without-search-form function to 'display-messages/forum-style/without-search-and-create. Renamed 'display-messages/forum-style/with-search-form function to 'display-messages/forum-style/with-search-and-create. Changed paths in 'message-action-cgi to correspond with new function naming conventions. Added 'display-create-button-forum function to 'search-forum' switch in 'message-action-cgi. Added 'classified-style object! within 'display-messages object! which includes 'with-search-and-create and 'without-search-and-create functions. Added 'classified' switch to 'message-action-cgi function. Ad ded 'display-create-form-classified function. Added 'display-create-button-classified and changed all references to 'display-create-button-forum in 'display-messages/classified-style object! to 'display-create-button-classified. Added 'create-classified' switch to 'message-action-cgi. Added 'display-search-form-classified function and changed all references to 'display-search-form-forum in 'display-messages/classified-style object! to 'display-search-form-classified. Removed redundant 'time-in-digits function code from decode-to-object! object! Added 'create-form-classified' switch to 'message-action-cgi." "Ryan"] ] Example: { Decode CGI input and create, display, edit, or delete message(s). This is the script's uber-function for CGI. message-action-cgi To decode CGI input from the web server: cgi-input: retrieve-user-data Using decoded CGI data, write XML standard message file to directory determined by messageType. create-message/from-cgi cgi-input Using an e-mail message or newsgroup message in the form of a REBOL e-mail object!, write XML standard message file to 'email' directory. create-message/from-email email-message Convert decoded CGI data into the standard message object!, overwriting a previously created message. edit-message cgi-input Delete a previously created message. delete-message cgi-input Using decoded CGI data containing messageID and messageType variables, either display a single message (messageID specified), a directory of messages (messageID = "none"), or an index of messages (messageID = "index") to the browser, including displaying the messageID and messageType to the reader. display-messages/for-reading/with-reference cgi-input Using decoded CGI data containing messageID and messageType variables, either display a single message (messageID specified), a directory of messages (messageID = "none"), or an index of messages (messageID = "index") to the browser, not displaying the messageID nor the messageType to the reader. display-messages/for-reading/without-reference cgi-input Using decoded CGI data containing messageID and messageType variables, either display a single message (messageID specified), a directory of messages (messageID = "none"), or an index of messages (messageID = "index") to the browser, including displaying the messageID and messageType to the reader, in an HTML form for editing. display-messages/for-editing/with-reference cgi-input } ] ;######################################## ;# CONFIGURATION # ;######################################## sessionID-timeout: make decimal! 1000 ;######################################## ;# FUNCTIONS # ;######################################## translate-message: make object! [ xml-tags: [ ["subject" "/subject"] ["author" "/author"] ["date" "/date"] ["content" "/content"] ["messageID" "/messageID"] ["messageType" "/messageType"] ] markup-data: func [ "Converts a standard message object! into a string containing the XML-format standard message." data [object!] "The standard message object!" ][ data-object: make data [] object-data: next first data-object output: copy "" for x 1 (length? xml-tags) 1 [ item: reform [rejoin ["data-object" "/" (first object-data)]] made-tag: rejoin ["" (build-tag [(xml-tags/1/1)]) (do item) (build-tag [(xml-tags/1/2)])] xml-tags: next xml-tags object-data: next object-data append output made-tag ] xml-tags: head xml-tags output ] read-markup: func [ "Converts a file containing the XML-format standard message into a standard message object!" xml-file [file!] "File containing the XML-format standard message." ][ message-data: load/markup xml-file xml-data: make object! [ subject: message-data/<subject> author: message-data/<author> date: message-data/<date> content: message-data/<content> messageID: message-data/<messageID> messageType: message-data/<messageType> ] xml-data ] ] decode-to-object: make object! [ from-cgi: func [ "Converts decoded CGI data into the standard message object!" cgi-data [object!] "Decoded CGI data." ][ make object! [ subject: cgi-data/subject author: cgi-data/author date: now content: cgi-data/content messageID: time-in-digits now messageType: cgi-data/messageType ] ] edited-from-cgi: func [ "Converts decoded CGI data into the standard message object!" cgi-data [object!] "Decoded CGI data." ][ make object! [ subject: cgi-data/subject author: cgi-data/author date: cgi-data/date content: cgi-data/content messageID: cgi-data/messageID messageType: cgi-data/messageType ] ] from-email: func [ "Converts the standard REBOL e-mail object! into the standard message object!" email-data [object!] "Standard REBOL e-mail object!" ][ make object! [ subject: email-data/subject author: email-data/from date: email-data/date content: email-data/content messageID: time-in-digits now messageType: "email" ] ] ] time-in-digits: func [ "Convert the date and time from 'now' into a string of digits." sun-dial [date!] "The current date and time from 'now'" ][ year: to-string sun-dial/year month: to-string sun-dial/month if (length? month) < 2 [insert month "0"] day: to-string sun-dial/day if (length? day) < 2 [insert day "0"] current-time: sun-dial/time hour: to-string current-time/hour if (length? hour) < 2 [insert hour "0"] minutes: to-string current-time/minute if (length? minutes) < 2 [insert minutes "0"] seconds: to-string current-time/second if (length? seconds) < 2 [insert seconds "0"] rejoin [year month day hour minutes seconds] ] retrieve-user-data: func [] [ return make object! decode-cgi either system/options/cgi/request-method = "POST" [ input ][ system/options/cgi/query-string ] ] write-xml-message: func [ "Write the XML-formatted standard message data with a file name determined by messageID and to a directory determined by messageType." xml-message-string [string!] "The XML-formatted standard message as it resides in memory as a string! datatype." ][ message-data: load/markup xml-message-string save-path: make file! (rejoin [message-data/<messageType> "/" message-data/<messageID>]) write/binary save-path xml-message-string ] read-message-directory: func [ "Read a directory of file names corresponding to a directory of XML-formatted standard messages with the directory determined by messageType." message-request-data [object!] "The data from the request to view messages, typically from an HTML form submitted to CGI." ][ message-directory: read (directory-name: make file! (rejoin [message-request-data/messageType "/"])) foreach message message-directory [ replace message message (make file! (rejoin [message-request-data/messageType "/" message])) ] message-directory ] read-message: func [ "Read a specific XML-formatted standard message with the directory determined by messageType and the file name determined by messageID." message-request-data [object!] "The data from the request to view a specific message, typically from an HTML form submitted to CGI." ][ message-directory: read (directory-name: make file! (rejoin [message-request-data/messageType "/" message-request-data/messageID])) ] read-directory-messages: func [ "Read a directory of XML-formatted standard messages with the directory determined by messageType." message-directory [block!] "A block of file names corresponding to a directory of XML-formatted standard messages." ][ message-block: copy [] sort/reverse message-directory foreach file-name message-directory [ file-contents: read file-name append message-block file-contents message-block ] ] display-markup: make object! [ xml-values: ["subject" "author" "date" "content" "messageID" "messageType"] css: func [ "Markup a standard message using standardized cascading style sheets tags as the display markup." xml-message-string [string!] "The XML-formatted standard message as it resides in memory as a string! datatype." ][ css-markup: copy [] standard-message-data: load/markup xml-message-string foreach value xml-values [ value-content: reform [rejoin ["standard-message-data" "/" "<" (first xml-values) ">"]] append css-markup (rejoin [{<div class="} value {">} (do value-content) {</div>}]) xml-values: next xml-values ] xml-values: head xml-values css-markup: make string! css-markup ] ] create-message: make object! [ from-cgi: func [ "Using decoded CGI data, writes XML standard message file to directory determined by messageType." cgi-input [object!] "Decoded CGI data as submitted from an HTML form." ][ standard-message-object: decode-to-object/from-cgi cgi-input xml-message-string: translate-message/markup-data standard-message-object write-xml-message xml-message-string ] from-email: func [ "Using an e-mail message in the form of a REBOL e-mail object!, writes XML standard message file to 'email' directory." email-message [object!] "E-mail message in the form of a REBOL e-mail object!" ][ standard-message-object: decode-to-object/from-email email-message xml-message-string: translate-message/markup-data standard-message-object write-xml-message xml-message-string ] ] edit-message: func [ "Converts decoded CGI data into the standard message object!, overwriting a previously created message." cgi-data [object!] "Decoded CGI data." ][ standard-message-object: decode-to-object/edited-from-cgi cgi-input xml-message-string: translate-message/markup-data standard-message-object write-xml-message xml-message-string ] delete-message: func [ "Deletes a previously created message." cgi-data [object!] "Decoded CGI data." ][ file-to-delete: make file! (rejoin [cgi-data/messageType "/" cgi-data/messageID]) delete file-to-delete ] get-messages-for-display: make object! [ all-messages-in-directory: make object! [ css-output: func [ "Using decoded CGI data, create a block! of messages marked up for display using standardized cascading style sheets tags as the display markup." cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID (set to none) sent as an appendage to the url request." ][ message-directory: read-message-directory cgi-input messages: read-directory-messages message-directory messages-for-display: copy [] foreach xml-message messages [ css-message: display-markup/css xml-message append messages-for-display css-message ] messages-for-display ] ] specific-message: make object! [ css-output: func [ "Using decoded CGI data, mark up a specific message for display using standardized cascading style sheets tags as the display markup." cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ file-path: make file! (rejoin [cgi-input/messageType "/" cgi-input/messageID]) xml-message: read file-path css-message: display-markup/css xml-message ] ] ] display-messages: make object! [ css-classes: ["subject" "author" "date" "content" "messageID" "messageType"] for-reading: make object! [ for-commenting: make object! [ with-search-form: func [ {Using decoded CGI data containing messageID and messageType variables, either display a single message (messageID specified), a directory of messages (messageID = "none"), or an index of messages (messageID = "index") to the browser, including displaying the messageID and messageType to the reader.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ switch/default cgi-input/messageID [ "none" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input display-search-form cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-comments-link this-messageID this-messageType ] ] "index" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input display-search-form cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "content" [ next css-classes ] "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-comments-link this-messageID this-messageType ] ] ][ message: get-messages-for-display/specific-message/css-output cgi-input display-search-form cgi-input foreach class css-classes [ switch/default class [ "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-comments-link this-messageID this-messageType ] ] without-search-form: func [ {Using decoded CGI data containing messageID and messageType variables, either display a single message (messageID specified), a directory of messages (messageID = "none"), or an index of messages (messageID = "index") to the browser, including displaying the messageID and messageType to the reader.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ switch/default cgi-input/messageID [ "none" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-comments-link this-messageID this-messageType ] ] "index" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "content" [ next css-classes ] "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-comments-link this-messageID this-messageType ] ] ][ message: get-messages-for-display/specific-message/css-output cgi-input foreach class css-classes [ switch/default class [ "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-comments-link this-messageID this-messageType ] ] ] no-commenting: make object! [ with-search-form: func [ {Using decoded CGI data containing messageID and messageType variables, either display a single message (messageID specified), a directory of messages (messageID = "none"), or an index of messages (messageID = "index") to the browser, including displaying the messageID and messageType to the reader.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ switch/default cgi-input/messageID [ "none" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input display-search-form cgi-input foreach message messages [ foreach class css-classes [ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] ] "index" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input display-search-form cgi-input foreach message messages [ foreach class css-classes [ either class = "content" [ next css-classes ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] ] ] ][ message: get-messages-for-display/specific-message/css-output cgi-input display-search-form cgi-input foreach class css-classes [ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] ] without-search-form: func [ {Using decoded CGI data containing messageID and messageType variables, either display a single message (messageID specified), a directory of messages (messageID = "none"), or an index of messages (messageID = "index") to the browser, including displaying the messageID and messageType to the reader.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ switch/default cgi-input/messageID [ "none" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input foreach message messages [ foreach class css-classes [ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] ] "index" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input foreach message messages [ foreach class css-classes [ either class = "content" [ next css-classes ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] ] ] ][ message: get-messages-for-display/specific-message/css-output cgi-input foreach class css-classes [ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] ] ] ] for-editing: make object! [ with-search-form: func [ {Using decoded CGI data containing messageID and messageType variables, either display a single message (messageID specified), a directory of messages (messageID = "none"), or an index of messages (messageID = "index") to the browser, including displaying the messageID and messageType to the reader, in an HTML form for editing.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ switch/default cgi-input/messageID [ "none" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input display-search-form cgi-input display-create-button cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-edit-message-button cgi-input this-messageID this-messageType display-delete-message-button cgi-input this-messageID this-messageType display-comments-edit-link cgi-input this-messageID this-messageType ] ] "index" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input display-search-form cgi-input display-create-button cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "content" [ next css-classes ] "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-edit-message-button cgi-input this-messageID this-messageType display-delete-message-button cgi-input this-messageID this-messageType display-comments-edit-link cgi-input this-messageID this-messageType ] ] ][ message: get-messages-for-display/specific-message/css-output cgi-input display-search-form cgi-input display-create-button cgi-input print {<FORM METHOD=GET ACTION="messages.cgi">} foreach class css-classes [ switch class [ "subject" [ pre-subject: {<INPUT TYPE="text" NAME="subject" VALUE="} css-tag: build-tag [div class (class)] parse/all message [thru css-tag copy text to </div> (item: copy text)] post-subject: {"><BR>} print rejoin [pre-subject item post-subject] ] "author" [ pre-author: {<INPUT TYPE="text" NAME="author" VALUE="} css-tag: build-tag [div class (class)] parse/all message [thru css-tag copy text to </div> (item: copy text)] post-author: {"><BR>} print rejoin [pre-author item post-author] ] "date" [ pre-date: {<INPUT TYPE="hidden" NAME="date" VALUE="} css-tag: build-tag [div class (class)] parse/all message [thru css-tag copy text to </div> (item: copy text)] post-date: {">} print rejoin [pre-date item post-date] ] "content" [ print {<TEXTAREA NAME="content" ROWS="24" COLS ="40">} css-tag: build-tag [div class (class)] parse/all message [thru css-tag copy text to </div> (print text)] print {</TEXTAREA><P>} ] "messageID" [ pre-messageID: {<INPUT TYPE="hidden" NAME ="messageID" VALUE="} css-tag: build-tag [div class (class)] parse/all message [thru css-tag copy text to </div> (item: copy text)] parse/all message [to css-tag copy text thru </div> (print text)] post-messageID: {">} print rejoin [pre-messageID item post-messageID] parse/all message [thru css-tag copy text to </div> (this-messageID: copy text)] ] "messageType" [ pre-messageType: {<INPUT TYPE="hidden" NAME ="messageType" VALUE="} css-tag: build-tag [div class (class)] parse/all message [thru css-tag copy text to </div> (item: copy text)] parse/all message [to css-tag copy text thru </div> (print text)] post-messageType: {">} print rejoin [pre-messageType item post-messageType] parse/all message [thru css-tag copy text to </div> (this-messageType: copy text)] ] ] ] pre-sessionID: {<INPUT TYPE="hidden" NAME="sessionID" VALUE ="} post-sessionID: {">} print rejoin [pre-sessionID cgi-input/sessionID post-sessionID] print {Edit the text above and then<BR><INPUT TYPE="radio" NAME="actionType" VALUE="edit"> Save Changes <INPUT TYPE="radio" NAME ="actionType" VALUE="delete"> Delete Message } print {<INPUT TYPE="submit" VALUE="Go!"></FORM>} display-comments-edit-link cgi-input this-messageID this-messageType ] ] without-search-form: func [ {Using decoded CGI data containing messageID and messageType variables, either display a single message (messageID specified), a directory of messages (messageID = "none"), or an index of messages (messageID = "index") to the browser, including displaying the messageID and messageType to the reader, in an HTML form for editing.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ switch/default cgi-input/messageID [ "none" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input display-create-button cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-edit-message-button cgi-input this-messageID this-messageType display-delete-message-button cgi-input this-messageID this-messageType display-comments-edit-link cgi-input this-messageID this-messageType ] ] "index" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input display-search-form cgi-input display-create-button cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "content" [ next css-classes ] "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-edit-message-button cgi-input this-messageID this-messageType display-delete-message-button cgi-input this-messageID this-messageType display-comments-edit-link cgi-input this-messageID this-messageType ] ] ][ message: get-messages-for-display/specific-message/css-output cgi-input display-create-button cgi-input print {<FORM METHOD=GET ACTION="messages.cgi">} foreach class css-classes [ switch class [ "subject" [ pre-subject: {<INPUT TYPE="text" NAME="subject" VALUE="} css-tag: build-tag [div class (class)] parse/all message [thru css-tag copy text to </div> (item: copy text)] post-subject: {"><BR>} print rejoin [pre-subject item post-subject] ] "author" [ pre-author: {<INPUT TYPE="text" NAME="author" VALUE="} css-tag: build-tag [div class (class)] parse/all message [thru css-tag copy text to </div> (item: copy text)] post-author: {"><BR>} print rejoin [pre-author item post-author] ] "date" [ pre-date: {<INPUT TYPE="hidden" NAME="date" VALUE="} css-tag: build-tag [div class (class)] parse/all message [thru css-tag copy text to </div> (item: copy text)] post-date: {">} print rejoin [pre-date item post-date] ] "content" [ print {<TEXTAREA NAME="content" ROWS="24" COLS ="40">} css-tag: build-tag [div class (class)] parse/all message [thru css-tag copy text to </div> (print text)] print {</TEXTAREA><P>} ] "messageID" [ pre-messageID: {<INPUT TYPE="hidden" NAME ="messageID" VALUE="} css-tag: build-tag [div class (class)] parse/all message [thru css-tag copy text to </div> (item: copy text)] parse/all message [to css-tag copy text thru </div> (print text)] post-messageID: {">} print rejoin [pre-messageID item post-messageID] parse/all message [thru css-tag copy text to </div> (this-messageID: copy text)] ] "messageType" [ pre-messageType: {<INPUT TYPE="hidden" NAME ="messageType" VALUE="} css-tag: build-tag [div class (class)] parse/all message [thru css-tag copy text to </div> (item: copy text)] parse/all message [to css-tag copy text thru </div> (print text)] post-messageType: {">} print rejoin [pre-messageType item post-messageType] parse/all message [thru css-tag copy text to </div> (this-messageType: copy text)] ] ] ] pre-sessionID: {<INPUT TYPE="hidden" NAME="sessionID" VALUE ="} post-sessionID: {">} print rejoin [pre-sessionID cgi-input/sessionID post-sessionID] print {Edit the text above and then<BR><INPUT TYPE="radio" NAME="actionType" VALUE="edit"> Save Changes <INPUT TYPE="radio" NAME ="actionType" VALUE="delete"> Delete Message } print {<INPUT TYPE="submit" VALUE="Go!"></FORM>} display-comments-edit-link cgi-input this-messageID this-messageType ] ] ] forum-style: make object! [ with-search-and-create: func [ {Using decoded CGI data containing messageID and messageType variables, either display a single message (messageID specified), a directory of messages (messageID = "none"), or an index of messages (messageID = "index") to the browser, including displaying the messageID and messageType to the reader.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ switch/default cgi-input/messageID [ "none" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input display-search-form-forum cgi-input display-create-button-forum cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-comments-forum-link this-messageID this-messageType ] ] "index" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input display-search-form-forum cgi-input display-create-button-forum cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "content" [ next css-classes ] "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-comments-forum-link this-messageID this-messageType ] ] ][ message: get-messages-for-display/specific-message/css-output cgi-input display-search-form-forum cgi-input display-create-button-forum cgi-input foreach class css-classes [ switch/default class [ "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-comments-forum-link this-messageID this-messageType ] ] without-search-and-create: func [ {Using decoded CGI data containing messageID and messageType variables, either display a single message (messageID specified), a directory of messages (messageID = "none"), or an index of messages (messageID = "index") to the browser, including displaying the messageID and messageType to the reader.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ switch/default cgi-input/messageID [ "none" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-comments-forum-link this-messageID this-messageType ] ] "index" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "content" [ next css-classes ] "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-comments-forum-link this-messageID this-messageType ] ] ][ message: get-messages-for-display/specific-message/css-output cgi-input foreach class css-classes [ switch/default class [ "messageID" [ return-div-text class message this-messageID: return-messageID class message ] "messageType" [ return-div-text class message this-messageType: return-messageType class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] display-comments-forum-link this-messageID this-messageType ] ] ] classified-style: make object! [ with-search-and-create: func [ {Using decoded CGI data containing messageID and messageType variables, either display a single message (messageID specified), a directory of messages (messageID = "none"), or an index of messages (messageID = "index") to the browser, including displaying the messageID and messageType to the reader.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ switch/default cgi-input/messageID [ "none" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input display-search-form-classified cgi-input display-create-button-classified cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "messageID" [ return-div-text class message ] "messageType" [ return-div-text class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] ] ] "index" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input display-search-form-classified cgi-input display-create-button-classified cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "content" [ next css-classes ] "messageID" [ return-div-text class message ] "messageType" [ return-div-text class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] ] ] ][ message: get-messages-for-display/specific-message/css-output cgi-input display-search-form-classified cgi-input display-create-button-classified cgi-input foreach class css-classes [ switch/default class [ "messageID" [ return-div-text class message ] "messageType" [ return-div-text class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] ] ] without-search-and-create: func [ {Using decoded CGI data containing messageID and messageType variables, either display a single message (messageID specified), a directory of messages (messageID = "none"), or an index of messages (messageID = "index") to the browser, including displaying the messageID and messageType to the reader.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ switch/default cgi-input/messageID [ "none" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "messageID" [ return-div-text class message ] "messageType" [ return-div-text class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] ] ] "index" [ messages: get-messages-for-display/all-messages-in-directory/css-output cgi-input foreach message messages [ foreach class css-classes [ switch/default class [ "content" [ next css-classes ] "messageID" [ return-div-text class message ] "messageType" [ return-div-text class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] ] ] ][ message: get-messages-for-display/specific-message/css-output cgi-input foreach class css-classes [ switch/default class [ "messageID" [ return-div-text class message ] "messageType" [ return-div-text class message ] ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] ] ] ] ] ] display-create-form: func [ {Display the HTML form used for message creation.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ print { <FORM METHOD=GET ACTION="messages.cgi"> <INPUT TYPE="hidden" NAME="actionType" VALUE="create"> } pre-messageType: {<INPUT TYPE="hidden" NAME="messageType" VALUE="} post-messageType: {">} print rejoin [pre-messageType cgi-input/messageType post-messageType] pre-sessionID: {<INPUT TYPE="hidden" NAME="sessionID" VALUE="} post-sessionID: {">} print rejoin [pre-sessionID cgi-input/sessionID post-sessionID] print { <INPUT TYPE="text" NAME="subject" VALUE="subject"><BR> <INPUT TYPE="text" NAME="author" VALUE="author"><BR> <TEXTAREA NAME="content" ROWS="24" COLS="40">content</TEXTAREA><BR> <INPUT TYPE="submit" VALUE="Save This Message!"> </FORM> } ] display-create-form-forum: func [ {Display the HTML form used for message creation.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ print { <FORM METHOD=GET ACTION="messages.cgi"> <INPUT TYPE="hidden" NAME="actionType" VALUE="create-forum"> } pre-messageType: {<INPUT TYPE="hidden" NAME="messageType" VALUE="} post-messageType: {">} print rejoin [pre-messageType cgi-input/messageType post-messageType] print { <INPUT TYPE="text" NAME="subject" VALUE="subject"><BR> <INPUT TYPE="text" NAME="author" VALUE="author"><BR> <TEXTAREA NAME="content" ROWS="24" COLS="40">content</TEXTAREA><BR> <INPUT TYPE="submit" VALUE="Save This Message!"> </FORM> } ] display-create-form-classified: func [ {Display the HTML form used for message creation.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ print { <FORM METHOD=GET ACTION="messages.cgi"> <INPUT TYPE="hidden" NAME="actionType" VALUE="create-classified"> } pre-messageType: {<INPUT TYPE="hidden" NAME="messageType" VALUE="} post-messageType: {">} print rejoin [pre-messageType cgi-input/messageType post-messageType] print { <INPUT TYPE="text" NAME="subject" VALUE="subject"><BR> <INPUT TYPE="text" NAME="author" VALUE="author"><BR> <TEXTAREA NAME="content" ROWS="24" COLS="40">content</TEXTAREA><BR> <INPUT TYPE="submit" VALUE="Save This Message!"> </FORM> } ] display-comment-form: func [ {Display the HTML form used for message creation.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ print { <FORM METHOD=GET ACTION="messages.cgi"> <INPUT TYPE="hidden" NAME="actionType" VALUE="comment"> } pre-messageType: {<INPUT TYPE="hidden" NAME="messageType" VALUE="} post-messageType: {">} print rejoin [pre-messageType cgi-input/messageType post-messageType] pre-parent-messageID: {<INPUT TYPE="hidden" NAME="parent-messageID" VALUE="} post-parent-messageID: {">} print rejoin [pre-parent-messageID cgi-input/parent-messageID post-parent-messageID] pre-parent-messageType: {<INPUT TYPE="hidden" NAME="parent-messageType" VALUE="} post-parent-messageType: {">} print rejoin [pre-parent-messageType cgi-input/parent-messageType post-parent-messageType] print { <INPUT TYPE="text" NAME="subject" VALUE="subject"><BR> <INPUT TYPE="text" NAME="author" VALUE="author"><BR> <TEXTAREA NAME="content" ROWS="24" COLS="40">content</TEXTAREA><BR> <INPUT TYPE="submit" VALUE="Save This Message!"> </FORM> } ] display-comment-form-forum: func [ {Display the HTML form used for message creation.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ print { <FORM METHOD=GET ACTION="messages.cgi"> <INPUT TYPE="hidden" NAME="actionType" VALUE="comment-forum"> } pre-messageType: {<INPUT TYPE="hidden" NAME="messageType" VALUE="} post-messageType: {">} print rejoin [pre-messageType cgi-input/messageType post-messageType] pre-parent-messageID: {<INPUT TYPE="hidden" NAME="parent-messageID" VALUE="} post-parent-messageID: {">} print rejoin [pre-parent-messageID cgi-input/parent-messageID post-parent-messageID] pre-parent-messageType: {<INPUT TYPE="hidden" NAME="parent-messageType" VALUE="} post-parent-messageType: {">} print rejoin [pre-parent-messageType cgi-input/parent-messageType post-parent-messageType] print { <INPUT TYPE="text" NAME="subject" VALUE="subject"><BR> <INPUT TYPE="text" NAME="author" VALUE="author"><BR> <TEXTAREA NAME="content" ROWS="24" COLS="40">content</TEXTAREA><BR> <INPUT TYPE="submit" VALUE="Save This Message!"> </FORM> } ] display-login-form: func [ {Display the HTML form used for logging in to use admin functions.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ print { <FORM METHOD=GET ACTION="messages.cgi"> <INPUT TYPE="hidden" NAME="actionType" VALUE="login"> } pre-messageType: {<INPUT TYPE="hidden" NAME="messageType" VALUE="} post-messageType: {">} print rejoin [pre-messageType cgi-input/messageType post-messageType] pre-messageID: {<INPUT TYPE="hidden" NAME="messageID" VALUE="} post-messageID: {">} print rejoin [pre-messageID cgi-input/messageID post-messageID] print { <INPUT TYPE="text" NAME="userID" VALUE="username"><BR> <INPUT TYPE="password" NAME="password" VALUE="password"><BR> <INPUT TYPE="submit" VALUE="Login!"> </FORM> } ] check-sessionID: func [ {Check a user's sessionID value to make sure it is still valid.} user-sessionID [string!] {The sessionID value as generated after login and continuously updated during a session.} sessionID-timeout [decimal!] {A decimal value representing the amount of time a user may be logged in to use administration functions without taking any action.} /local sessionID-check ][ user-sessionID: make decimal! user-sessionID sessionID-check: make decimal! time-in-digits now return either (user-sessionID + sessionID-timeout) > sessionID-check [ true ][ false ] ] search-messages: func [ "Searches a directory of messages for a keyword match and returns a block of messageIDs for messages containing the keyword." cgi-data [object!] "Decoded CGI data." /local message-directory messages messages-with-keyword xml-message this-message message-with-keyword ][ message-directory: read-message-directory cgi-data messages: read-directory-messages message-directory messages-with-keyword: copy [] foreach xml-message messages [ if find xml-message cgi-data/keyword [ message-with-keyword: load/markup xml-message append messages-with-keyword message-with-keyword/<messageID> ] ] messages-with-keyword ] display-search-form: func [ {Display the HTML form used for searching messages for a keyword.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ print rejoin [{<FORM METHOD=GET ACTION="messages.cgi"><INPUT TYPE ="hidden" NAME="actionType" VALUE="search"><INPUT TYPE="hidden" NAME ="messageType" VALUE="} cgi-input/messageType {"><INPUT TYPE="hidden" NAME ="messageID" VALUE="none"><INPUT TYPE="text" NAME="keyword" VALUE ="keyword"><INPUT TYPE="submit" VALUE="Search } cgi-input/messageType {!"></FORM>}] ] display-search-form-forum: func [ {Display the HTML form used for searching messages for a keyword.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ print rejoin [{<FORM METHOD=GET ACTION="messages.cgi"><INPUT TYPE ="hidden" NAME="actionType" VALUE="search-forum"><INPUT TYPE="hidden" NAME ="messageType" VALUE="} cgi-input/messageType {"><INPUT TYPE="hidden" NAME ="messageID" VALUE="none"><INPUT TYPE="text" NAME="keyword" VALUE ="keyword"><INPUT TYPE="submit" VALUE="Search } cgi-input/messageType {!"></FORM>}] ] display-search-form-classified: func [ {Display the HTML form used for searching messages for a keyword.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ print rejoin [{<FORM METHOD=GET ACTION="messages.cgi"><INPUT TYPE ="hidden" NAME="actionType" VALUE="search-classified"><INPUT TYPE="hidden" NAME="messageType" VALUE="} cgi-input/messageType {"><INPUT TYPE="hidden" NAME="messageID" VALUE="none"><INPUT TYPE="text" NAME="keyword" VALUE ="keyword"><INPUT TYPE="submit" VALUE="Search } cgi-input/messageType {!"></FORM>}] ] display-create-button: func [ {Display the HTML form used to generate a message creation form.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ print rejoin [{<FORM METHOD=GET ACTION="messages.cgi"><INPUT TYPE ="hidden" NAME="actionType" VALUE="create-form"><INPUT TYPE="hidden" NAME ="messageType" VALUE="} cgi-input/messageType {"><INPUT TYPE="hidden" NAME ="sessionID" VALUE="} cgi-input/sessionID {"><INPUT TYPE="submit" VALUE ="Create New Message!"></FORM><P>}] ] display-create-button-forum: func [ {Display the HTML form used to generate a message creation form.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ print rejoin [{<FORM METHOD=GET ACTION="messages.cgi"><INPUT TYPE ="hidden" NAME="actionType" VALUE="create-form-forum"><INPUT TYPE="hidden" NAME="messageType" VALUE="} cgi-input/messageType {"><INPUT TYPE="submit" VALUE="Create New Message!"></FORM><P>}] ] display-create-button-classified: func [ {Display the HTML form used to generate a message creation form.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ print rejoin [{<FORM METHOD=GET ACTION="messages.cgi"><INPUT TYPE ="hidden" NAME="actionType" VALUE="create-form-classified"><INPUT TYPE ="hidden" NAME="messageType" VALUE="} cgi-input/messageType {"><INPUT TYPE ="submit" VALUE="Create New Message!"></FORM><P>}] ] display-edit-message-button: func [ {Display the HTML form used to generate a message editing form.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." this-messageID [string!] {The messageID of a specific message as parsed from a string.} this-messageType [string!] {The messageType of a specific message as parsed from a string.} ][ print rejoin [{<FORM METHOD=GET ACTION="messages.cgi"><INPUT TYPE ="hidden" NAME="messageID" VALUE="} this-messageID {"><INPUT TYPE="hidden" NAME="messageType" VALUE="} this-messageType {"><INPUT TYPE="hidden" NAME ="sessionID" VALUE="} cgi-input/sessionID {"><INPUT TYPE="hidden" NAME ="actionType" VALUE="edit-form"><INPUT TYPE="submit" VALUE="Edit Message"></FORM>}] ] display-delete-message-button: func [ {Display the HTML form used to generate a message editing form.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." this-messageID [string!] {The messageID of a specific message as parsed from a string.} this-messageType [string!] {The messageType of a specific message as parsed from a string.} ][ print rejoin [{<FORM METHOD=GET ACTION="messages.cgi"><INPUT TYPE ="hidden" NAME="messageID" VALUE="} this-messageID {"><INPUT TYPE="hidden" NAME="messageType" VALUE="} this-messageType {"><INPUT TYPE="hidden" NAME ="sessionID" VALUE="} cgi-input/sessionID {"><INPUT TYPE="hidden" NAME ="actionType" VALUE="delete"><INPUT TYPE="submit" VALUE="Delete Message"></FORM>}] ] display-comments-link: func [ {Display a link which will will send a CGI request to show the comments related to a message.} this-messageID [string!] {The messageID of a specific message as parsed from a string.} this-messageType [string!] {The messageType of a specific message as parsed from a string.} ][ print rejoin [{<DIV class="commentlink"><A HREF ="messages.cgi?actionType=display-comments&messageType=} this-messageType {&messageID=} this-messageID {">Post/View Comments</A></DIV>}] ] display-comments-edit-link: func [ {Display a link which will will send a CGI request to show the comments related to a message.} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." this-messageID [string!] {The messageID of a specific message as parsed from a string.} this-messageType [string!] {The messageType of a specific message as parsed from a string.} ][ print rejoin [{<DIV class="commentlink"><A HREF ="messages.cgi?actionType=display-comments-edit&messageType=} this-messageType {&messageID=} this-messageID {&sessionID=} cgi-input/sessionID {">Post/View Comments</A></DIV>}] ] display-comments-forum-link: func [ {Display a link which will will send a CGI request to show the comments related to a message.} this-messageID [string!] {The messageID of a specific message as parsed from a string.} this-messageType [string!] {The messageType of a specific message as parsed from a string.} ][ print rejoin [{<DIV class="commentlink"><A HREF ="messages.cgi?actionType=display-comments-forum&messageType=} this-messageType {&messageID=} this-messageID {">Post/View Comments</A></DIV>}] ] return-div-text: func [ {Return a portion of a message, including its <DIV> tags.} class [string!] {A div class name} message [string!] {A message marked up with CSS-classed <DIV> tags.} /local css-tag ][ css-tag: build-tag [div class (class)] parse/all message [to css-tag copy text thru </div> (print text)] ] return-messageID: func [ class [string!] {A div class name} message [string!] {A message marked up with CSS-classed <DIV> tags.} /local css-tag this-messageID ][ css-tag: build-tag [div class (class)] parse/all message [thru css-tag copy text to </div> (this-messageID: copy text)] this-messageID ] return-messageType: func [ class [string!] {A div class name} message [string!] {A message marked up with CSS-classed <DIV> tags.} /local css-tag this-messageType ][ css-tag: build-tag [div class (class)] parse/all message [thru css-tag copy text to </div> (this-messageType: copy text)] this-messageType ] message-action-cgi: func [ {Decode CGI input and create, display, edit, or delete message(s).} cgi-input [object!] "Decoded CGI data as submitted from an HTML page, most likely sent using GET with messageType and messageID sent as an appendage to the url request." ][ print "Content-Type: text/html^/" default-input: make cgi-input [ messageID: "none" ] if error? try [ stylesheet-to-load: make file! (rejoin [cgi-input/messageType ".css"]) stylesheet: read stylesheet-to-load ][ stylesheet-to-load: %comments.css stylesheet: read stylesheet-to-load ] print { <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE></TITLE> } print {<STYLE type="text/css">} print stylesheet print {</STYLE>} print { </HEAD> <BODY> } switch/default cgi-input/actionType [ "create-form" [ either (check-sessionID cgi-input/sessionID sessionID-timeout) [ display-create-form cgi-input ][ display-login-form cgi-input ] ] "create-form-forum" [ display-create-form-forum cgi-input ] "create-form-classified" [ display-create-form-classified cgi-input ] "create" [ either (check-sessionID cgi-input/sessionID sessionID-timeout) [ create-message/from-cgi cgi-input display-messages/for-editing/with-search-form default-input ][ display-login-form cgi-input ] ] "create-forum" [ create-message/from-cgi cgi-input display-messages/forum-style/with-search-and-create default-input ] "create-classified" [ create-message/from-cgi cgi-input display-messages/classified-style/with-search-and-create default-input ] "comment" [ if error? try [ create-message/from-cgi cgi-input ][ comments-directory: make file! rejoin [cgi-input/messageType {/}] make-dir comments-directory create-message/from-cgi cgi-input ] parent-message-input: make cgi-input [ messageType: cgi-input/parent-messageType messageID: cgi-input/parent-messageID ] post-comment-input: make cgi-input [ messageType: cgi-input/parent-messageID messageID: "none" ] post-comment-reverse-input: make cgi-input [ messageID: "none" messageType: parent-message-input/messageID parent-messageID: parent-message-input/messageID parent-messageType: parent-message-input/messageType ] display-messages/for-reading/for-commenting/with-search-form parent-message-input wait 1 display-messages/for-reading/for-commenting/without-search-form post-comment-input display-comment-form post-comment-reverse-input ] "comment-forum" [ if error? try [ create-message/from-cgi cgi-input ][ comments-directory: make file! rejoin [cgi-input/messageType {/}] make-dir comments-directory create-message/from-cgi cgi-input ] parent-message-input: make cgi-input [ messageType: cgi-input/parent-messageType messageID: cgi-input/parent-messageID ] post-comment-input: make cgi-input [ messageType: cgi-input/parent-messageID messageID: "none" ] post-comment-reverse-input: make cgi-input [ messageID: "none" messageType: parent-message-input/messageID parent-messageID: parent-message-input/messageID parent-messageType: parent-message-input/messageType ] display-messages/forum-style/with-search-and-create parent-message-input wait 1 display-messages/forum-style/without-search-and-create post-comment-input display-comment-form-forum post-comment-reverse-input ] "display" [ if error? try [display-messages/for-reading/for-commenting/with-search-form cgi-input][] ] "forum" [ if error? try [display-messages/forum-style/with-search-and-create cgi-input][] ] "classified" [ if error? try [display-messages/classified-style/with-search-and-create cgi-input][] ] "search" [ searched-messages: search-messages cgi-input display-search-form cgi-input foreach searched-message searched-messages [ search-cgi-input: make cgi-input [ messageID: searched-message ] display-messages/for-reading/for-commenting/without-search-form search-cgi-input ] ] "search-forum" [ searched-messages: search-messages cgi-input display-create-button-forum cgi-input display-search-form-forum cgi-input foreach searched-message searched-messages [ search-cgi-input: make cgi-input [ messageID: searched-message ] display-messages/forum-style/without-search-and-create search-cgi-input ] ] "search-classified" [ searched-messages: search-messages cgi-input display-create-button-classified cgi-input display-search-form-classified cgi-input foreach searched-message searched-messages [ search-cgi-input: make cgi-input [ messageID: searched-message ] display-messages/classified-style/without-search-and-create search-cgi-input ] ] "display-comments" [ reverse-input: make cgi-input [ messageID: "none" messageType: cgi-input/messageID parent-messageID: cgi-input/messageID parent-messageType: cgi-input/messageType ] display-messages/for-reading/for-commenting/with-search-form cgi-input if error? try [display-messages/for-reading/for-commenting/without-search-form reverse-input][] display-comment-form reverse-input ] "display-comments-edit" [ either (check-sessionID cgi-input/sessionID sessionID-timeout) [ reverse-input: make cgi-input [ messageID: "none" messageType: cgi-input/messageID parent-messageID: cgi-input/messageID parent-messageType: cgi-input/messageType ] display-messages/for-reading/for-commenting/with-search-form cgi-input if error? try [display-messages/for-editing/without-search-form reverse-input][] ][ display-login-form cgi-input ] ] "display-comments-forum" [ reverse-input: make cgi-input [ messageID: "none" messageType: cgi-input/messageID parent-messageID: cgi-input/messageID parent-messageType: cgi-input/messageType ] display-messages/forum-style/with-search-and-create cgi-input if error? try [display-messages/forum-style/without-search-and-create reverse-input][] display-comment-form-forum reverse-input ] "edit-form" [ either (check-sessionID cgi-input/sessionID sessionID-timeout) [ display-messages/for-editing/with-search-form cgi-input ][ display-login-form cgi-input ] ] "edit" [ either (check-sessionID cgi-input/sessionID sessionID-timeout) [ edit-message cgi-input display-messages/for-editing/with-search-form default-input ][ display-login-form cgi-input ] ] "delete" [ either (check-sessionID cgi-input/sessionID sessionID-timeout) [ delete-message cgi-input display-messages/for-editing/with-search-form default-input ][ display-login-form cgi-input ] ] "display-login" [ display-login-form cgi-input ] "login" [ unencrypted-logins: decrypt read %logins.bin do unencrypted-logins login: make object! [ userID: cgi-input/userID password: cgi-input/password ] login-string: make string! logins either all [(find/any/case login-string login/userID) (find/any/case login-string login/password)][ cgi-input: make cgi-input [ sessionID: make decimal! time-in-digits now ] display-messages/for-editing/with-search-form cgi-input ][ display-login-form cgi-input ] ] ][ display-messages/for-reading/for-commenting/with-search-form default-input ] print { </BODY> </HTML> } ] encrypt-logins: func [ {Encrypt login usernames and passwords.} logins [string!] {A string containing the 'login word and a database of usernames and associated passwords.} ][ write/binary %logins.bin encrypt {logins:[["username1" "password1"] ["username2" "password2"]]} ] ;#################################################################### ;# # ;# BOHDAN LECHNOWSKY'S ENCRYPT.R # ;# # ;# REBOL [ # ;# Title: "En-/decryption Functions" # ;# Date: 20-Jul-1999 # ;# Author: "Bohdan Lechnowsky" # ;# File: %encrypt.r # ;# Purpose: "A basic encryption scheme." # ;# Usage: { # ;# Put the command: # ;# # ;# do %encrypt.r # ;# # ;# near the beginning of your %user.r file. Once # ;# it has been run, do the following: # ;# # ;# >> write/binary %pass.r encrypt "password-here" # ;# # ;# Whenever you need to assign that particular # ;# password, do the following (this example shows # ;# setting the default proxy password): # ;# # ;# system/schemes/default/proxy/pass: decrypt read %pass.r # ;# } # ;# Category: [file util 3] # ;# ] # ;# # ;#################################################################### hash: func [ "Returns a hash value for a string" string [string!] value [integer!] ][ (checksum string) // value ] encrypt: func [ "Encrypts a string" string [string!] /local shift-val codeword ][ codeword: "mycode" ;-- change as needed shift-val: hash codeword 8 if zero? shift-val [shift-val: 5] string: shift enbase/base compress string 2 shift-val to-string load append insert head string "2#{" "}" ] decrypt: func [ "Decrypts an encrypted string" string [string!] /local shift-val codeword ][ codeword: "mycode" ;-- change as needed shift-val: hash codeword 8 if zero? shift-val [shift-val: 5] string: shift/right enbase/base string 2 shift-val to-string decompress load append insert head string "2#{" "}" ] shift: func [ "Takes a base-2 binary string and shifts bits" data [string!] places [integer!] /left /right /local first-bits last-bits ][ if any [places < 1 places >= length? data] [ print "ERROR: Shift places exceeds length of binary data or is invalid" return none ] either right [ last-bits: copy/part tail data (places * -1) remove/part tail data (places * -1) data: head insert head data last-bits ][ first-bits: copy/part data places remove/part data places append data first-bits ] return data ] ;######################################## ;# PROGRAM # ;######################################## ; if error? try [ cgi-input: retrieve-user-data message-action-cgi cgi-input ;][ ; no-cgi-input: make object! [ ; actionType: "display" ; messageType: "news" ; messageID: "none" ; ] ; message-action-cgi no-cgi-input ;] Ryan C. Christiansen Web Developer Intellisol International 4733 Amber Valley Parkway Fargo, ND 58104 701-235-3390 ext. 6671 FAX: 701-235-9940 http://www.intellisol.com Global Leader in People Performance Software _____________________________________ Confidentiality Notice This message may contain privileged and confidential information. If you think, for any reason, that this message may have been addressed to you in error, you must not disseminate, copy or take any action in reliance on it, and we would ask you to notify us immediately by return email to [EMAIL PROTECTED] -- To unsubscribe from this list, please send an email to [EMAIL PROTECTED] with "unsubscribe" in the subject, without the quotes.