Creating a message board
As an example of the flexibility of Ariadne, this tutorial will show you how to build a threaded message board (or forum) with just the standard Ariadne components. No new classes are needed, just a few simple object templates will do.
For this example the message board will use normal directory objects as topics and page objects as messages. The root of the message board uses a site object. Public users are able to reply to topics, but cannot create new topics.
The object structure will look something like this:
/messageboard/ -> psite
/messageboard/topic/ -> pdir
/messageboard/topic/message/ -> ppage
All templates are defined on the root of the messageboard: /messageboard/.
The first step is to create a template to view a message or topic: view.html. We define this template on the page class:
<html>
<body>
<h1><pinp> echo $nlsdata->name; </pinp></h1>
<p><pinp> echo $nlsdata->summary; </pinp></p>
<pinp>
$site=currentsite();
$topic=substr($path, strlen($site));
$topic=substr($topic, 0, strpos($topic, '/')+1);
putvar("current", $path);
get($site.$topic, "show.thread.html");
</pinp>
<form action="reply.html">
<table>
<tr>
<td align="right">Title:</td>
<td>
<input type="text" name="title" maxlength="50">
</td>
</tr><tr>
<td align="right" valign="top">Text:</td>
<td>
<textarea name="summary" cols="50" rows="8"></textarea>
</td>
</tr><tr>
<td></td>
<td><input type="submit" value="OK"></td>
</tr>
</table>
</form>
</body>
</html>
This template shows the title and body of a message. Then it calculates the path of the topic to which the current message belongs, and calls a template on that topic to show the full thread of replies. Finally it shows a form to allow people to reply to a message.
The path of the topic is calculated by removing the first part of the path of the current object, which corresponds with the path of the current site, the root of the message board. The next part of the path, upto the first '/', is the path of the topic.
The current path is made available to other templates with the putvar() function. This will later be used to highlight the current message in the threaded view.
Finally the "show.thread.html" template is called on the topic, which we've just calculated.
The show.thread.html template then looks like this:
<a href="<pinp> echo make_url(".."); </pinp>">List Topics</a>
<pinp>
$query="object.implements='ppage'";
find($query, "show.html");
</pinp>
The threaded view will start with a link to the root of the message board, which will list all the topics. Then it calls "show.html" on all page objects (and descendants, you never know..) below it. The threading magic is all in the show.html template:
<pinp>
$indent=count(explode('/', $parent))-3;
$current=getvar("current");
</pinp>
<div style='margin-left: <pinp> echo ($indent*16) </pinp>px'>
<pinp>
if ($current==$path) { echo "<b>"; }
</pinp>
<a href="<pinp> echo make_url(); </pinp>"><pinp>
echo $nlsdata->name;
</pinp></a>
<pinp>
if ($current==$path) { echo "</b>"; }
</pinp>
</div>
This template simply calculates the amount of indentation needed based on the number of '/' characters in its' path. Each '/' in the path means it has one more parent. In this case I've subtracted 3 from the total, to make up for the root (the psite object) of the message board. You could calculate this in the show.thread.html template, and pass it on as a variable. The calculated indentation is used to set the left margin, via the style setting of the <DIV> block containing the link to the message. But you can use any other method you want to indent the message.
Next it retrieves the path of the 'current' message and checks it against its own path. If they match, the link is made bold. This highlights the current message in the threaded view.
The next template to build is the 'reply.html' template. This template will check user input and add a new message.
<pinp>
$title=getvar("title");
// remove all html from the title:
$title=strip_tags($title);
// maximum title length: 50
$title=substr($title, 0, 50);
$summary=getvar("summary");
// allow only links, bold, italic and underline
$summary=strip_tags($summary,"<a><i><u><b>");
// now set the arguments for a new page
$args[$nls]["name"]=$title;
$args[$nls]["summary"]=$summary;
$args["arNewFilename"]='{5:id}';
$args["arNewType"]="ppage";
call("system.new.phtml", $args);
// finally redirect the browser to the
// current message
ldRedirect(make_url());
</pinp>
After all the checks are done, the next step is to create an argument list for the system.new.phtml template. This template needs a filename, an object type and the name and summary of the object, in the current language.
The filename is set to '{5:id}', this means that Ariadne will calculate a unique id, and pad it out to 5 characters, filling it up with 0's. This is important, as the default ordering of objects by find (and ls) is alfabetical. Using padded numbers, this will automatically order new pages below older pages.
Now, these template together will already make a working message board. However, the list of topics is currently not done. The next two templates will create a list of topics, with the number of messages per topic. The first template is the default view.html template for the psite object:
<html>
<body>
<h1><pinp> echo $nlsdata->name; </pinp></h1>
<p><pinp> echo $nlsdata->summary; </pinp></p>
<pinp>
ls("show.topic.html");
</pinp>
</body>
</html>
The final template is the show.topic.html template, defined on the ppage class:
<a href="<pinp> echo make_url(); </pinp>"><pinp>
echo $nlsdata->name; </pinp></a>
<pinp> echo count_find("object.type=='ppage'"); </pinp> replies.<br>
Now we have a working messageboard, except for one thing: you must be logged on to post or read messages. So the final step is to add the correct grants to make your messageboard public. These grants must allow the public user to read the messageboard, and to add messages to topics. So in /messageboard/ add these grants for the user (or group) public:
read, >add(ppage)
The add grant is modified so it is only valid for objects of type ppage and only starting at a topic. The public user is not allowed to add a new topic, only messages below existing topics.
With this the message board is finished. It could use a bit of a facelift though, but that would make the templates too complex for this tutorial. A messageboard with a bit more flesh around the bones can be downloaded here . Make sure you include the grants in the import, if you want the message board to be writable by everyone.