Skip to page content or Skip to Accesskey List.

Work

Main Page Content

The Abcs Of Cms Part Iv

Rated 3.88 (Ratings: 8)

Want more?

 
Picture of Jay Blanchard

Jay Blanchard

Member info

User since: 21 Mar 2001

Articles written: 6

A Little Story

The first content management system I ever created (in 1996) wasn't called a content management system. It was called an automatic article posting script (AAPS), except it wasn't all that automatic. I am sure that many web developers during that time period wrote something similar to reduce the flow of information across their desks. Here was the "workflow";

  • An author wrote an article using a plain text editor
  • The author uploaded the file to a specific directory via FTP
  • The author sent an email to an editor about the article
  • The editor either telneted in and edited the article using vi, emacs, or pico OR downlaoded the text file via FTP, edited the file, and uploaded it via FTP.
  • Once uploaded, the editor could go to a web form, select the text file, input a title, teaser and author information, and then process the article (via a neat little Perl script);
    • The script opened an existing template and rewrote the template, adding the stuff the editor entered, as well as stuff from the text file, line by line, placing proper <h> and <p> tags where needed.
    • The that file was saved with a temporary name and then renamed according to the naming convention established by the group using the AAPS. Then it was moved to the proper directory.
    • A copy of the front page of the web site was made, then it was opened by the script. The title (as a link to the newly created HTML article), teaser, and posting time were added to the duplicate home page "template".
    • The original home page was renamed as index.html.old. Then the (thank goodness for Perl's speed) home page template was renamed index.html

  • Voila! The article appeared on the front page of the site.
  • Since there were HTML pages for each article those had to be downloaded and removed from the site time to time, manually.
  • The front page would have to be manually edited from time to time to remove links to articles
  • And this is exactly what the site owner wanted at the time!

Occasionally there would be some sort of weird error, like an author not adhering to the established naming conventions or mis-naming his or her text file, causing two HTML pages to be created with the same name, and therefore the same link. Other times the CGI engine would be a little erratic due to server traffic and do funky things to the article. All of this required manual repair. But it worked very well, every day, and served the site for over a year.

The single largest burden carried by members of the site's staff was carried by the editors. Often authors uploaded articles and failed to let editors know in a timely manner. Editors were looking at the upload file from time to time each day to find new articles, sometimes they forgot to delete a file after it was processed, another editor would go through again, re-edit and re-post the article. This caused email notification to be added to the Perl script (which they did not want originally because authors would often include additional information in their emails to the editors about the article in question).

We have come a long, long way since then!

Editing Articles

After clearing the login page the editor is sent to editor.php where he or she is presented with navigation suitable for their access level and a list of articles assigned to them at the author level. Similar to the My Articles page, the editor page has links to review articles as well as links to edit the article. Articles are flagged as edited by using the type input box on the form where editing is accomplished. The editor will be given a chance to save the article without forwarding it through the workflow process, or they may go ahead and submit the page as 'edited'. As you will soon see, we will use the 'type' input to progress the article through the completion of the process.

You will have to ask yourself and your client some questions at this point about what the editor will be allowed to do.

  • Will an editor also be able to submit articles? If so you need to give them a link to the article submission page (especially easy if you created that handy-dandy navigation management interface suggested in Part II of this series).
  • Do you want them to have access to a list of their articles? Then there will have to be a 'My Articles' link for the editor.

While we will not be venturing down those roads in this series, they are questions for which you are equipped to provide solutions. These questions will come up time and again throughout the CMS design process as you move through the workflow (i.e. the persons at this level also need to be able to do these other things, like submit articles).

First, add the navigation items to the table for the editor access level;

INSERT INTO tblNavigation (URL, accesslevel) VALUES ('<a href="editor.php" title="Edit Articles">Edit Articles</a>', 'editor');

INSERT INTO tblNavigation (URL, accesslevel) VALUES ('<a href="eduser.php" title="Edit User Information">Edit User Information</a>', 'editor');

Let's get the editing process started with editor.php;

<? session_start(); ?>

<?

//connect to and select database

if(!($dbconnect = mysql_pconnect("127.0.0.1", "cms_user", "cms_password"))){

print("Failed to connect to database!

");

exit();

}

if(!mysql_select_db("cms", $dbconnect)){

print("Failed to select database!

");

exit();

}

//query to get navigation from database

$qnav = "SELECT URL ";

$qnav .= "FROM tblNavigation ";

$qnav .= "WHERE accesslevel = '$level' ";

if(!($dbnav = mysql_query($qnav, $dbconnect))){

print("MySQL reports: " . mysql_error() . "

");

exit();

}

//query to get article information

$qart = "SELECT a.ID, a.title, a.publish, a.author, a.editor, a.type, a.submitted, u.email, u.name ";

$qart .= "FROM tblArticle a, tblUser u ";

$qart .= "WHERE a.editor = u.name ";

if(!($dbart = mysql_query($qart, $dbconnect))){

print("MySQL reports: " . mysql_error() . "

");

exit();

}

?>

<html>

<head>

<title>CMS</title>

<LINK REL="StyleSheet" HREF="cms.css" type="text/css">

</head>

<body>

<div class="left">

<?

while($dbrow = mysql_fetch_object($dbnav)){

print($dbrow->URL . "<br>

");

}

?>

</div>

<div class="right">

<?

$dbartrow = mysql_fetch_object($dbart);

if($dbartrow->ID == ""){

//if there are no articles for this editor

print("There are no articles assigned to you currently in the Content Management System");

}

else

{

//print article links for this editor

mysql_data_seek($dbart, 0);

print("<h3>Welcome " . $dbartrow->name . "</h3>

");

print("These are the articles currently assigned to you for editing;<br><br>

");

while($dbartrow = mysql_fetch_object($dbart)){

if($dbartrow->type != "edited"){

print("<a href=\"artprvw.php?aid=" . $dbartrow->ID . "\">" . $dbartrow->title . "</a> ( <a href=\"edart.php?aid=" . $dbartrow->ID . "\">Edit</a> ) Submitted: " . $dbartrow->submitted . "<br>

");

}

}

}

?>

</div>

</body>

</html>

Just as we did with the authors there is a way for the editor to preview the article, by clicking on its title, or a way to edit the article. Also note that to the right of each article's information is the date that the article was submitted for editing, and is ordered in such a way as to show articles that have been in the queue longest at the top of the list.

Note: No form validation has been undertaken in this series so as not to distract from the primary purpose of basic design of a CMS from the ground up. You can consider some of these items, such as submission date, to be covered in training ["If you fail to enter the submission date when submitting an article it will fall later on the editor's to-do list."], or you can programatically handle these items.

Here is the edart.php page where the editor actually does the editing;

<? session_start(); ?>

<?

//connect to and select database

if(!($dbconnect = mysql_pconnect("127.0.0.1", "cms_user", "cms_password"))){

print("Failed to connect to database!

");

exit();

}

if(!mysql_select_db("cms", $dbconnect)){

print("Failed to select database!

");

exit();

}

//query to get navigation from database

$qnav = "SELECT URL ";

$qnav .= "FROM tblNavigation ";

$qnav .= "WHERE accesslevel = '$level' ";

if(!($dbnav = mysql_query($qnav, $dbconnect))){

print("MySQL reports: " . mysql_error() . "

");

exit();

}

//query to get article information

$qart = "SELECT a.ID, a.title, a.author, a.teaser, a.body ";

$qart .= "FROM tblArticle a ";

$qart .= "WHERE a.ID = $aid ";

if(!($dbart = mysql_query($qart, $dbconnect))){

print("MySQL reports: " . mysql_error() . "

");

exit();

}

//place database items in variables for easier manipulation

$dbartrow = mysql_fetch_object($dbart);

$atitle = $dbartrow->title;

$aauthor = $dbartrow->author;

$ateaser = $dbartrow->teaser;

$abody = $dbartrow->body;

?>

<html>

<head>

<title>CMS</title>

<LINK REL="StyleSheet" HREF="cms.css" type="text/css">

</head>

<body>

<div class="left">

<?

// list the nav links for this type of user

while($dbrow = mysql_fetch_object($dbnav)){

print($dbrow->URL . "<br>

");

}

?>

</div>

<div class="right">

<h1>Edit An Article</h1>

<form action="cmsedit.php" method="POST">

<table cellpadding="3" cellspacing="0" border="1">

<tr>

<td>Article Title</td>

<input type="hidden" name="aid" value="<? print($aid) ; ?>">

<td><input type="text" name="title" size="64" maxlength="64" value="<? print($atitle); ?>"></td>

</tr>

<tr>

<td>Author </td>

<td><? print($aauthor) ?></td>

</tr>

<tr>

<td>Article Teaser</td>

<td><textarea name="teaser" cols="50" rows="3" wrap="virtual" maxlength="255"><? print($ateaser); ?></textarea></td>

</tr>

<tr>

<td>Article Body</td>

<td><textarea name="body" cols="50" rows="25" wrap="virtual"><? print($abody); ?></textarea></td>

</tr>

<tr>

<td>Article Status</td>

<td><input type="text" name="type" size="32" maxlength="32" value="edited"></td>

</tr>

<tr>

<td>

</td>

<td valign="top">

<input type="submit" name="action" value="Save"><br>

<input type="submit" name="action" value="Submit Article"><br>

<input type="submit" name="action" value="Reject Article"><br>

<input type="reset">

</td>

</tr>

</table>

</form>

</div>

</body>

</html>

You will see that there are options for the editor to save, submit, and now 'reject' the article, plus one other piece of input; the Article Status. Article Status will be set to 'edited' and saved in the database only when the editor submits the article further up the workflow process. Later we will change this bit of data to indicate where the article is in the workflow process. We will explore this further after we create cmsedit.php.

<? session_start(); ?>

<?

//connect to and select database

if(!($dbconnect = mysql_pconnect("127.0.0.1", "cms_user", "niicms"))){

print("Failed to connect to database!

");

exit();

}

if(!mysql_select_db("cms", $dbconnect)){

print("Failed to select database!

");

exit();

}

// perform action based on which button was pushed on submit form

switch($action)

{

case "Save":

// query to insert saved elements only

$qsave = "UPDATE tblArticle ";

$qsave .= "SET title = '$title', ";

$qsave .= "teaser = '$teaser', ";

$qsave .= "body = '$body' ";

$qsave .= "WHERE ID = '$aid' ";

if(!($dbsave = mysql_query($qsave, $dbconnect))){

print("MySQL reports: " . mysql_error() . "<br>

");

exit();

}

break;

case "Submit Article":

//query to submit article

$qsubmit = "UPDATE tblArticle ";

$qsubmit .= "SET title = '$title', ";

$qsubmit .= "teaser = '$teaser', ";

$qsubmit .= "body = '$body', ";

$qsubmit .= "type = '$type' ";

$qsubmit .= "WHERE ID = '$aid' ";

if(!($dbsubmit = mysql_query($qsubmit, $dbconnect))){

print("MySQL reports: " . mysql_error() . "<br>

");

exit();

}

//select admin information and send an email

$qadmin = "SELECT email ";

$qadmin .= "FROM tblUser ";

$qadmin .= "WHERE accesslevel = 'admin' ";

if(!($dbadmin = mysql_query($qadmin, $dbconnect))){

print("MySQL reports this: " . mysql_error() . "<br>

");

exit();

}

//message to admin

$dbadmin = mysql_fetch_object($dbadmin);

$messadmin = "The following article, $title, has been edited.

";

$messadmin .= "Please review this article at your earliest convenience.

";

mail("$dbadmin->email", "CMS Article Submission", $messadmin, "From: CMS System");

break;

case "Reject Article":

//query to clear editor field

$qclearedit = "UPDATE tblArticle ";

$qclearedit .= "SET editor = NULL ";

$qclearedit .= "WHERE ID = '$aid' ";

if(!($dbclearedit = mysql_query($qclearedit, $dbconnect))){

print("MySQL reports this: " . mysql_error() . "<br>

");

exit();

}

//message to author

$messauthor = "The following article, $title, has been rejected by your editor.

";

$messauthor .= "Please contact your editor to determine the necessary

";

$messauthor .= "measures to prepare the article for publication.

";

mail("$author", "CMS Article Submission", $messauthor, "From: CMS System");

break;

}

header("Location: editor.php"); exit;

?>

Let's have a look at a couple of things. First, the code following case "Save": saves only the title, teaser, and body of the article, no flag is set for the Article Status field, even though the word "edited" appears in the form. This allows an editor to work on an article a little bit at a time, until editing duties are complete.

If the article is submitted the title, teaser, and body are updated and the Article Status flag $type is set to "edited". This removes the article from editor.php and sends an email to the administrator, informing admin that there is an article waiting for approval. You can add a field to the edart.php for the entry of an approval or admin's so that an admin can be selected (depending on workflow needs). This is similar to how we selected an editor earlier.

Ah rejection! If the article is rejected the editor is set to NULL and an email will be sent to the author informing them. You could include a field in the editing form for editor's comments or have the author contact his editor via email. Once the article is rejected it appears again in the My Articles page for the author.

Sharpening The System

Thus far in the series there has be a lot of information to absorb and process, no doubt leading to many other ideas for how to use and how to code various features for your CMS and other web-based applications. Approval duties will be covered next as we move the article through the workflow process, plus we will begin to explore other ideas and improvements that could be made to the system we are using as our model.

A long time code-jockey Jay enjoys music (especially horn bands like Tower of Power, Chicago and Here Come The Mummies), furniture building, physics, motorcycle riding and philosophy. His latest projects include several business-specific web-based tools and widgets.

Jay lives in Central Texas, but has never forgotten his South Louisiana heritage. His daughters, Kaitlyn and Brittany, are his inspiration!

The access keys for this page are: ALT (Control on a Mac) plus:

evolt.org Evolt.org is an all-volunteer resource for web developers made up of a discussion list, a browser archive, and member-submitted articles. This article is the property of its author, please do not redistribute or use elsewhere without checking with the author.