📄 ch18.htm
字号:
<HTML>
<HEAD>
<TITLE>Chapter 18 -- Discussion Formus </TITLE>
<META>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">
<H1><FONT COLOR=#FF0000>Chapter 18</FONT></H1>
<H1><B><FONT SIZE=5 COLOR=#FF0000>Discussion Forums</FONT></B>
</H1>
<P>
<HR WIDTH="100%"></P>
<P>
<H3 ALIGN=CENTER><FONT COLOR="#000000"><FONT SIZE=+2>CONTENTS<A NAME="CONTENTS"></A>
</FONT></FONT></H3>
<UL>
<LI><A HREF="#DiscussionForumsEverythingOldIsNew" >Discussion Forums-Everything Old Is New Again</A>
<LI><A HREF="#DiscussionForumDisplayandBistateCGI" >Discussion Forum Display and Bistate CGI Programming</A>
<LI><A HREF="#UsefulDataFieldsforDiscussionForums" >Useful Data Fields for Discussion Forums and Parent/Sibling/Child Relationships</A>
<LI><A HREF="#ADiscussionForumExample" >A Discussion Forum Example </A>
<LI><A HREF="#DiscussionForumAdministration" >Discussion Forum Administration</A>
<UL>
<LI><A HREF="#RemovePostingbyDate" >Remove Posting by Date</A>
<LI><A HREF="#RemoveThreadbyDate" >Remove Thread by Date</A>
<LI><A HREF="#RemovePostingbyAuthor" >Remove Posting by Author</A>
<LI><A HREF="#RemoveIndividualPostings" >Remove Individual Postings</A>
<LI><A HREF="#RemoveIndividualThreads" >Remove Individual Threads</A>
</UL>
<LI><A HREF="#DiscussionForumAdditions" >Discussion Forum Additions</A>
<LI><A HREF="#SelectiveSortingCriteria" >Selective Sorting Criteria</A>
<LI><A HREF="#SearchEngines" >Search Engines</A>
<LI><A HREF="#RegisteredUsersandhtaccessSchemes" >Registered Users and .htaccess Schemes</A>
<LI><A HREF="#Summary" >Summary</A>
</UL>
<HR>
<P>
The World Wide Web discussion forum is a new way to deliver information
the way Usenet newsgroups and computer bulletin board services
have for years. The hyperlinking nature of the Web has made this
migration quite natural for users and relatively simple to program
through the Common Gateway Interface.
<H2><A NAME="DiscussionForumsEverythingOldIsNew"><FONT SIZE=5 COLOR=#FF0000>Discussion
Forums-Everything Old Is New Again</FONT></A></H2>
<P>
Prior to the explosion of the World Wide Web, the User Network
(Usenet) newsgroups were the most popular service on the Internet.
They allowed users from all over the world to carry on a sort
of "public discussion." The protocol used to transfer
this information took heavily from the e-mail protocol, and local
systems were obliged to, in essence, keep a local copy of Usenet
for its users or face severe performance penalties. Usenet is
still very popular today. In Usenet, you can find discussion groups
on thousands of subjects.
<P>
Something very similar to Usenet can be simulated on the World
Wide Web through CGI programming: a discussion forum. In fact,
the earliest versions of Netscape allowed users to read Usenet
newsgroups by parsing news articles and displaying them as HTML
within the main Netscape client window. In this chapter, I'm going
to accomplish the following:
<UL>
<LI>Discuss the bistate display of a discussion forum
<LI>Plan data fields
<LI>Explore the concept of a threaded discussion forum
<LI>Develop a discussion forum
<LI>Explore discussion forum administration, including some accompanying
source code
<LI>Offer suggestions as to extra features a discussion forum
may have
</UL>
<H2><A NAME="DiscussionForumDisplayandBistateCGI"><FONT SIZE=5 COLOR=#FF0000>Discussion
Forum Display and Bistate CGI Programming</FONT></A></H2>
<P>
Though my opinions on a lot of things can run counter to the norm,
when it comes to the display of a discussion forum, there tends
to be a general degree of agreement between other programmers
and me. Discussion forums tend to have two sorts of displays:
an entry-level display and a display for people who are actually
reading the postings within. This concept is demonstrated in Figure
18.1.
<P>
<A HREF="f18-1.gif" ><B>Figure 18.1:</B> <I>An outline of how discussion forums will look for users both entering into the forum and read.</I></A>
<P>
Though the ends are generally agreed upon, the means can differ.
Entries within a discussion forum can either be full HTML documents
that are updated as needed, or they can be stored as files of
information possessing header fields and a body area that are
processed as needed by the CGI program and displayed from within
the CGI. There are good arguments for both methods: creating "ready-made"
HTML documents requires no CGI involvement at view-time, so pages
can be displayed faster when being viewed. Dynamic presentation
of postings can give a discussion forum much greater information-handling
capabilities should they be required. For instance, if you wanted
to create an auxiliary CGI program or routine that would display
only messages by a given author, it would be much more straightforward
to generate this sort of report if your data was handled as data
files rather than as full HTML documents.
<P>
I often talk about the capability of CGI programs to be "multistate";
that is, they can present different faces to the user depending
on circumstances. Circumstances include <TT><FONT FACE="Courier">GET</FONT></TT>/<TT><FONT FACE="Courier">POST</FONT></TT>
information, environment variables (the IP the user is accessing
the CGI program from, what browser he or she is using, what link
the user clicked on to get to the CGI, and so on), the time of
day, the HTTPd system load, phase of the moon, or just about anything
else that can vary. I find that discussion forums naturally lend
themselves to a very special multistate configuration-a bistate.
<P>
The division between just entering into the discussion forum and
reading through it is an obvious one. In the first case, only
two general areas are needed: a list of postings and a form for
entering in your own posting.
<P>
If we are currently reading a posting, the discussion forum should
display three areas: the contents of the posting being read, a
list of related postings, and a form to submit a new posting.
Any submission from the form in this area will relate the submission
to the current posting. Also, this form can include "prequoted"
text from the current posting to help the poster refer to specific
elements in the message being replied to.
<H2><A NAME="UsefulDataFieldsforDiscussionForums"><FONT SIZE=5 COLOR=#FF0000>Useful
Data Fields for Discussion Forums and Parent/Sibling/Child Relationships</FONT></A>
</H2>
<P>
Any posting in a discussion forum obviously includes a message
body. Beyond that we get to choose what data fields we think are
important to have included in a message. Here are the data fields
that have gained general acceptance:
<UL>
<LI>A subject line.
<LI>A To: field.
<LI>The name or handle of the author.
<LI>The author's e-mail address.
<LI>The time and date of posting. This is automatically generated
by the discussion forum CGI.
<LI>The ID number of the posting to which the current posting
is a reply.
<LI>The ID numbers of all postings that reply to this posting.
</UL>
<P>
The first five fields in this list strongly resemble what you'd
find in an e-mail. Part of this stems from the historical organization
of discussion lists, but mostly these five fields are here because
this sort of organization scheme just makes sense. The remaining
two fields allow the CGI system to "thread" discussions.
<P>
Threading turns what might otherwise be white noise babble into
meaningful conversations. After reading a message, the reader
is given the opportunity to reply. The two messages are linked
to each other with the reply as a "child message" and
the first message as the "parent." A parent can have
many children, which are "siblings." The discussion
forum is responsible for organizing its postings in a way that
reflects these familial relationships. On the Web, discussion
forums often take advantage of the ordered and unordered list
features of HTML. Figure 18.2 is a screen shot of the London Chat
BBS, a discussion forum I have attached to one of my chat rooms.
It illustrates the use of HTML list features to "thread"
postings.
<P>
<A HREF="f18-2.gif" ><B>Figure 18.2: </B><I>The London Chat BBS shows how discussion forums are well matched to Chat Rooms.</I></A>
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
The parent/sibling/child scheme is a way of conceptualizing the "tree" data structure. If ever you want to design a particularly complicated discussion forum, it might be useful to consult a reference on trees. The Art of Computer Programming by
Donald Knuth is the classic book in the field of data structures, but it likely would be overkill for your problem. Any good book store or library should be able to cough up a book that will work out for you. I use Data Structures and Program Design in C
by Kruse, Leung, and Tondo.</BLOCKQUOTE>
</TD></TR>
</TABLE></CENTER>
<P>
<BR>
<H2><A NAME="ADiscussionForumExample"><FONT SIZE=5 COLOR=#FF0000>A
Discussion Forum Example</FONT></A></H2>
<P>
Listing 18.1 is the source code for my example discussion forum.
It works along the model of CGI processing of data files rather
than generation of complete HTML documents. You can see this discussion
forum on-line at
<BLOCKQUOTE>
<TT><FONT FACE="Courier"><A HREF="http://www.anadas.com/cgiunleashed/discussion/forum.cgi">http://www.anadas.com/cgiunleashed/discussion/forum.cgi</A></FONT></TT>
</BLOCKQUOTE>
<HR>
<BLOCKQUOTE>
<B>Listing 18.1. <FONT SIZE=2 FACE="MCPdigital-B">forum.cgi</FONT>-A
"threaded discussion forum" CGI program, written in
Perl.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">#!/usr/bin/perl<BR>
<BR>
#<BR>
# This program was written by Richard Dice of Anadas Software
Development<BR>
# as part of the Sams Net "CGI Programming Unleashed"
book. The author<BR>
# intends this code to be used for instructional purposes and
not for<BR>
# resale or commercial gain.<BR>
#<BR>
# Any questions or comments regarding this program are welcome. You
<BR>
# may contact the author by Internet email: rdice@anadas.com<BR>
#<BR>
<BR>
# --- Configuration Variables ---<BR>
$prog_url = 'http://www.anadas.com/cgiunleashed/discussion/forum.cgi';
<BR>
<BR>
#<BR>
# the Query String is treated as a prefix to qualify which forum
postings<BR>
# are ones of interest. <BR>
#<BR>
$prefix = $ENV{QUERY_STRING};<BR>
<BR>
# --- start of GET/POST method handler ---<BR>
<BR>
# puts all POST query information the variable $input_line<BR>
read(STDIN, $input_line, $ENV{CONTENT_LENGTH});<BR>
<BR>
# replace all '+' coded spaces with real spaces<BR>
$input_line =~ tr/+/ /;<BR>
<BR>
# creates array of all data files in $input_line from & separated
info<BR>
@fields = split(/\&/,$input_line);<BR>
undef($input_line); # free up memory<BR>
<BR>
#<BR>
# decodes hex info for each name/value pair and places pairs in
<BR>
# %input associative array<BR>
#<BR>
foreach $i (0 .. $#fields) {<BR>
($name,$value) = split(/=/,$fields[$i]);<BR>
$name =~ s/%(..)/pack("c",hex($1))/ge;
<BR>
$value =~ s/%(..)/pack("c",hex($1))/ge;
<BR>
$input{$name} = $value;<BR>
}<BR>
<BR>
# --- end of GET/POST method handler ---<BR>
<BR>
#<BR>
# should this page be accessed with form data and having a refering
URL<BR>
# different from $prog_url, someone is attempting to post data
from<BR>
# an invalid form -- exit the program with error message<BR>
#<BR>
if ( defined(%input) || ($ENV{HTTP_REFERER} ne $prog_url) ) {
<BR>
&referer_error;<BR>
}<BR>
<BR>
if ( $input{'submit'} eq 'Submit this Article' ) {<BR>
&new_article;<BR>
print "Location: $prog_url?$input{'basepost'}\n\n";
<BR>
exit 0;<BR>
}<BR>
<BR>
#<BR>
# gets the names of all relevent posting files and puts in the
@posts array<BR>
#<BR>
&get_posts($prefix);<BR>
<BR>
if ( $prefix eq '' ) {<BR>
&print_header;<BR>
&print_list;<BR>
&print_form;<BR>
&print_footer;<BR>
} else {<BR>
<BR>
&read_article($prefix);<BR>
<BR>
&print_header;<BR>
&print_posting;<BR>
&print_list;<BR>
&print_form;<BR>
&print_footer;<BR>
}<BR>
<BR>
exit 0;<BR>
<BR>
sub print_header {<BR>
<BR>
print "Content-type: text/html\n\n";
<BR>
if ( $prefix eq '' ) {<BR>
print <<END;<BR>
<HTML><HEAD><TITLE>Discussion Forum</TITLE></HEAD>
<BR>
<BODY><BR>
<P><BR>
<H3>All Discussion Forum Postings</H3><BR>
END<BR>
} else {<BR>
print "<HTML><HEAD><TITLE>Posting:
$title</TITLE></HEAD>\n";<BR>
print "<BODY>\n";
<BR>
print "<P>\n";
<BR>
print "<A HREF=$prog_url>Return
to Discussion Forum front page</A>\n";<BR>
}<BR>
}<BR>
<BR>
sub referer_error {<BR>
<BR>
print <<END;<BR>
<HTML><HEAD><TITLE>Refering URL Error!</TITLE></HEAD>
<BR>
<BODY><BR>
<P><BR>
The form which was submitted to this CGI program did not originate
with<BR>
this program. This is forbidden.<BR>
<P><BR>
<A HREF=$prog_url>Return to the Discussion Forum</A>
<BR>
</BODY></HTML><BR>
END<BR>
<BR>
}<BR>
<BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -