Location: PHPKode > projects > Lame Node System > lns-0.6-11/include/HTMLFactory.php
<?php

/************************************************************************
 *																		*
 * Copyright (C) 2001 Stuart Reeves										*
 *																		*
 * This program is free software; you can redistribute it and/or		*
 * modify it under the terms of the GNU General Public License			*
 * as published by the Free Software Foundation; either version 2		*
 * of the License, or (at your option) any later version.				*
 *																		*
 * This program is distributed in the hope that it will be useful,		*
 * but WITHOUT ANY WARRANTY; without even the implied warranty of		*
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the			*
 * GNU General Public License for more details.							*
 * 																		*
 * The GNU General Public License is available from:					*
 * http://www.gnu.org/copyleft/gpl.html									*
 *																		*
 ************************************************************************/

/* Stuart's lns (lame node system) */



/* HTMLFactory provides a theme-able HTML environment for the pages. The themes are found in the 
 * THEME_PATH directory and extend the HTMLFactory class. They follow this layout:
 * 
 *  	themes/<themename>/default.css		- stylesheet of the theme
 *						  /header.html
 *						  /footer.html
 *						  /nodecontent.html
 *						  /miniview.html
 *
 * Directives for the HTML files have this format: %%d_<command name>%%
 *
 */



class HTMLFactory
{


	var $themePath,		// Full pathname of the particular theme
		$directives, 	// A list of the command directives that may be parsed
		$theme, 		// The current theme
		$username,		// The currently logged in user (if any)
		$protected,
		$silentupdate,	// Silent update is a three state value. Unset indicates 
						// it is not necessary, otherwise it is boolean.
		$superuser;
		

	// Constructor	
	function HTMLFactory($theme, $nodename) {
	
		$this->themePath 	= THEME_PATH . "/$theme";
		$this->theme 		= $theme;
		$this->protected	= false;
		$this->superuser	= false;
		
		// Set up the commands
		$this->directives[d_NODENAME]  			= stripslashes($nodename);
		$this->directives[d_PAGE_TITLE] 		= HTML_TITLE;
		$this->directives[d_HOME_NODE] 			= HOME_NODE;
		$this->directives[d_HOME_NODE_TEXT]		= "home";
		$this->directives[d_THEME_PATH] 		= $this->themePath;
		$this->directives[d_SEARCH_NODE] 		= SEARCH_NODE;
		$this->directives[d_SUBMIT_NODE] 		= SUBMIT_NODE;
		$this->directives[d_SHOW_ALL_NODE] 		= LIST_NODE;		// *** Deprecated
		$this->directives[d_SHOW_LATEST_NODE]	
							= LIST_NODE."&listmode=bytimestamp"; 	// *** Deprecated
		$this->directives[d_LIST_NODE]			= LIST_NODE;
		$this->directives[d_COPYTEXT]  			= COPYTEXT;
		$this->directives[d_SELECT_THEME_NODE]  = PREFERENCES_NODE; // *** Deprecated
		$this->directives[d_PREFERENCES_NODE]	= PREFERENCES_NODE;
		$this->directives[d_LOGIN_STATE]		= LOGIN_NODE;		// Set by setUsername()
		$this->directives[d_USERNAME]			= "";				// Set by setUsername()
		$this->directives[d_FINGER_NODE]		= FINGER_NODE;
		$this->directives[d_WHO_NODE]			= WHO_NODE;
		$this->directives[d_NEW_USER_NODE]		= NEW_USER_NODE;
		$this->directives[d_HELP_NODE]			= HELP_NODE . "#$nodename";
		$this->directives[d_DATE]				= date("d/m/y");
		$this->directives[d_DAY]				= date("l");
		$this->directives[d_CURRENT_THEME]		= $theme;
		$this->directives[d_NODE_METATYPE]		= "";
		$this->directives[d_NODE_RAWTYPE]		= RAWTYPE_DEFAULT;
		// The following can only be set when calling createNodePreview() or createNodeMiniView()
		$this->directives[d_MINIVIEW_NODENAME]	= "";
		$this->directives[d_MINIVIEW_TEXTBODY]	= "";
		$this->directives[d_MINIVIEW_METATYPE]	= "";
		// createNodeMiniView() calls only
		$this->directives[d_SCORE]				= 0;
		//
		$this->directives[d_RELATED_NODES]		= "";
		$this->directives[d_NODE_CONTENT]		= "";
		$this->directives[d_FIRST_EDITOR]		= "";
		
	}



	/* Mini helper function */
	function parseDirectivesCB($cmd) {
		return $this->directives[$cmd[1]];
	}



	/* Parses a file for an d_IF [!]<directive> <contents> d_FI statement. If the statement 
	 * evalulates as true (i.e. <directive> is not empty, which means that it has been set and
	 * therefore needs to be displayed), then the outer keywords and directive will be removed,
	 * leaving the contents.
	 *
	 * Args:	$cmd (array)		- Array of regular expression match results
	 * 
	 * Returns:	$cmd[3] (string) 	- The contents of the command for further parsing */
	 
	function parseIfCommandCB($cmd) {

		// cmd[2] will be the directive to evaluate, cmd[1] the potential NOT (!) modifier
		// and cmd[3] the contents of the statement
		
		// Hack: doesn't seem to work otherwise
		$value = $this->directives[$cmd[2]];
		global $this;
		
		if ($value || $cmd[1] == '!')
			return $cmd[3];
		else 
			return "";
		
	}
	 

	/* Args:	$nodename			- The node we are viewing (if the constructor nodename setting
	 *								  is out of date) */
	function setNodename($nodename) {
		$this->directives[d_NODENAME] = stripslashes($nodename);
	}

	
	/* Args:	$nodename			- The name of the home node (i.e. differs from HOME_NODE) */
	function setHomeNode($nodename) {
		$this->directives[d_HOME_NODE] 		= stripslashes($nodename);
		$this->directives[d_HOME_NODE_TEXT] = "your home node";
	}


	/* Args: 	$username			- The currently logged in user */
	function setUsername($username) {
		if (isset($username)) {
			$this->username 				 = $username;
			$this->directives[d_LOGIN_STATE] = LOGOUT_NODE;
			$this->directives[d_USERNAME]	 = $username;
		} else {
			// Clear the variables
			$this->username 				 = "";
			$this->directives[d_LOGIN_STATE] = LOGIN_NODE;
			$this->directives[d_USERNAME]	 = "";
		}
	}

	function setProtected($flag) {
		$this->protected = $flag;
	}

	function setSilentUpdate($flag) {
		if ($flag)
			$this->silentupdate = true;
		else
			$this->silentupdate = false;
	}

	function setSuperuser($flag) {
		$this->superuser = $flag;
	}

	
	function setTypes($rawType, $metaType) {
		$this->directives[d_NODE_RAWTYPE]  = $rawType;
		$this->directives[d_NODE_METATYPE] = $metaType;
	}


	function setRelatedNodes($relatedNodes) {
		
		$rows 		   = ceil(sqrt(sizeof($relatedNodes)));
		$relNodesHTML .= "<table cellpadding=\"5\" cellspacing=\"0\" class=\"relatednodes\">";
		$arrayIdx	   = 0;
		
		for ($i = 0; $i < $rows; ++$i) {
			$relNodesHTML .= "<tr>";
			for ($j = 0; $j < $rows; ++$j) {
				$relatedNode = $relatedNodes[$arrayIdx];
				if ($relatedNode != "") {
					$relNodesHTML .= "<td align=\"center\" class=\"relatednodes\">" . 
									 "<a title=\"$relatedNode\" href=\"?node=$relatedNode\">" .											 "$relatedNode</a></td>\n";
				} else {
					$relNodesHTML .= "<td class=\"relatednodes\">" . 
									 "&nbsp;</td>\n";
				}
				++$arrayIdx;
			}
			$relNodesHTML .= "</tr>\n";
		}
				
		$relNodesHTML .= "</table>";
		
		$this->directives[d_RELATED_NODES] = $relNodesHTML;

	}


	function setNodeContent($nodeContent) {
		if (!$nodeContent) {
			$nodeContent = "I've tried to find it, but you have selected a node which " . 
						   "doesn't exist.<br /> Why don't you <a href=\"?node=" . 
						   SUBMIT_NODE . "&_nodename=" . $this->directives[d_NODENAME] . 
						   "\">create this node</a>?";
		}
				
		$this->directives[d_NODE_CONTENT] = $nodeContent;
	}


	function appendNodeContent($nodeContent) {
		$this->directives[d_NODE_CONTENT] .= $nodeContent;	
	}

	
	function setFirstEditor($firstEditor) {
		$this->directives[d_FIRST_EDITOR] = $firstEditor;
	}

	
	/* Parses an HTML and inserts relevent text based on directives. The directives are of this
	 * format: %%<directive>%%
	 * 
	 * Args:	$htmlfile (string)	- The HTML filename to create a parsed version from
	 *
	 * Returns: $html (string)  	- The fully parsed HTML
	 *			false (boolean) 	- Error reading/writing the source or destination files */
	 
	function parseThemeHTML($HTMLFile) {

		$parsedHTML = "";

		// Check whether a freshly parsed file needs to be created (i.e. if $htmlfile.html.parsed 
		// does not exist)	
		//if (!file_exists("$this->themePath/$HTMLFile.parsed")) {
		
			// Read the source HTML file that contains the directives
			if ($fp1 = fopen("$this->themePath/$HTMLFile", "r")) {
				
				$content = fread($fp1, filesize("$this->themePath/$HTMLFile"));
			
				$parsedHTML = 
					preg_replace_callback("/%~\s*IF\s+(!)?(\w+)\s*~%([" . ALLOWED_NODENAME_CHARS . 
										  "\"\/\?\[\]\(\)#%:\<\>]*)%~\s*FI\s*~%/",
										  array($this, 'parseIfCommandCB'), 
										  $content);

				// Use a callback to replace any directives in the HTML string
				$parsedHTML = preg_replace_callback("/%%(\w+)%%/", 
							    					array($this, 'parseDirectivesCB'), 
													$parsedHTML);
			
				// Write the parsed file to disk
				//$fp2 = fopen("$this->themePath/$HTMLFile.parsed", "w");
				//fwrite($fp2, $parsedHTML);
			
				fclose($fp1);
				//fclose($fp2);
			} else
				return false;
			
			
		//}
		
		/*$fp = fopen("$this->themePath/$HTMLFile.parsed", "r");
		if ($fp) { 
			$html .= fread($fp, filesize("$this->themePath/$HTMLFile.parsed"));
			fclose($fp);
			return $html;
		} else
			return false;*/
			
			return $parsedHTML;

	}



	/* Wrapper function for creating an HTML header
	 *
	 * Returns: $html (string)  	- parsed HTML header for the current theme */

	function createHeader() {

		$html = "";
		if ($html = $this->parseThemeHTML(THEME_HEADER_FILE))
			return HEADER_COMMENT . $html;
		else
			return "ERROR: Cannot open current theme \"$this->theme\" header file<br />";

	}



	/* Wrapper function for creating an HTML footer.
	 *
	 * Returns: $html (string)  	- parsed HTML footer for the current theme */

	function createFooter(){
		$html = "";
		if ($html = $this->parseThemeHTML(THEME_FOOTER_FILE))
			return $html;
		else
			return "ERROR: Cannot open current theme \"$this->theme\" footer file<br />";
	}



	/* Wrapper function for creating the node content. (The d_NODE_CONTENT directive has been
	 * filled either by the NodeInterface object or calls to the HTMLFactory object).
	 *
	 * Returns: $html (string)  	- parsed HTML footer for the current theme */

	function createNodeContent() {
		$html = "";
		if ($html = $this->parseThemeHTML(THEME_NODE_CONTENT_FILE))
			return $html;
		else
			return "ERROR: Cannot open current theme \"$this->theme\" node file<br />";
	}



	/* Wrapper function for creating a truncated miniature version of a node
	 *
	 * Args:	$html				- Textbody to insert into mini view	
	 *			$args[1]			- (Optional) Nodename to insert into mini view
	 *			$args[2]			- (Optional) The ranking of the item (if relevant)
	 *			$args[3]			- (Optional) The metatype of this node 
	 *
	 * Returns:	$html				- The resulting HTML segment */
	
	function createNodeMiniView($html) {
	
		$args = func_get_args();
	
		$this->directives[d_MINIVIEW_TEXTBODY] = $html;
		$this->directives[d_MINIVIEW_NODENAME] = $args[1];
		$this->directives[d_SCORE]  		   = $args[2];
		$this->directives[d_MINIVIEW_METATYPE] = $args[3];
		
		$html = "";
		if ($html = $this->parseThemeHTML(THEME_NODE_MINIVIEW_FILE)) {
			return $html;
		} else {
			return "ERROR: Cannot open current theme \"$this->theme\" node mini view file<br />";
		}
		
	}



	/* Creates a node submit form.
	 *
	 * Args:	$script (string)		- Referring script
	 *			$nodename ...
	 *				$metatype (strings)	- Field values */

	function createSubmitForm($script, 
							  $nodename, 
							  $author, 
							  $contact, 
							  $link, 
							  $text, 
							  $metatype) {

		$html = "
	
<form action=\"$script\" method=\"post\" name=\"submit\">
<table border=\"0\">
<tr>
	<td>node name:</td>
	<td><input type=\"text\" name=\"_nodename\" size=\"20\" value=\"$nodename\"></td>
	<td> node type: <select name=\"_metatype\">";

		global $NODE_METATYPES;
		
		foreach ($NODE_METATYPES as $nodeMetatype) {

			// Anonymous users are not allowed to see the type METATYPE_HOME
			if ($nodeMetatype != METATYPE_HOME || isset($this->username)) {
				$selected = "";
				if (isset($metatype) && $metatype == $nodeMetatype)
					$selected = " selected";
				
				$html .= "<option value=\"$nodeMetatype\"$selected>$nodeMetatype\n";
			}
		}

		$html .= "
		</select>
	</td>
</tr>";

		if (!isset($this->username)) {
			$html .= "
<tr>
	<td>your name:</td>
	<td colspan=\"2\"><input type=\"text\" name=\"_author\" size=\"20\" value=\"$author\"></td>
</tr>
<tr>
	<td>contact (web or email):</td>
	<td colspan=\"2\"><input type=\"text\" name=\"_contact\" size=\"20\" value=\"$contact\"></td>
</tr>
			";
			
		} else if ($this->superuser) {
		
			$checked = "";
			if ($this->protected) 
				$checked = " checked";
				
			$html .= "
<tr>
	<td>protect node:</td>
	<td colspan=\"2\"><input type=\"checkbox\" name=\"_protected\"$checked></td>
</tr>
			";
		}

		if (isset($this->silentupdate) && isset($this->username) && 
			($text != "" || $link != "")) {
			
			$checked = "";
			if ($this->silentupdate)
				$checked = " checked";
			$html .= "
<tr>
	<td>silent update:</td>
	<td colspan=\"2\"><input type=\"checkbox\" name=\"_silentupdate\"$checked> <a href=\"?node=" . 
	HELP_NODE . "#silentupdate\">help</a></td>
</tr>
			";
		}
		

		$html .= "
</table>

<br />

<dl>
	<dt><div class=\"subtitle\">Basic Information <span class=\"warning\">(Important!)</span>
		</div>
	If you wish to link to another node, put square brackets (\"[\" and \"]\") round the text in the
	textbox below. For instance, if the following text is put in the box:<br /></dt>
		<dd><i>I wanna link to the node about [me me me]</i></dd>
	<dt>then this text will be created when you submit:</dt>
		<dd><i>I wanna link to the node about <a href=\"?node=me me me\">me me me</a></i></dd>
	<dt>The second way to enter links is by using a bar (\"|\") character to replace the
	displayed text:<br/></dt>
		<dd>I wanna link to the node [me me me|about myself]</dd>
	<dt>which creates:</dt>
		<dd><i>I wanna link to the node <a href=\"?node=me me me\">about myself</a></i></dd>
	<dt>Try entering some text and hitting the \"preview\" button below to test the results!</dt>
</dl>

type your text here:
<div align=\"left\">
<textarea cols=\"75\" rows=\"25\" name=\"_text\" wrap=\"virtual\">$text</textarea>
<a href=\"?node=" . HELP_NODE . "#enteringtext\">help</a>

<br /><br />

You can enter a link to a picture or another website with the textbox below. Entering a website 
address will enable you to create a node that redirects to the entered website. 
<span class=\"warning\">Please note:</span> any text entered to the box above will be <b>ignored</b>
if you fill in the following field with the address of a website (e.g. \"http://www.mysite.com\").

<table border=\"0\">
<tr>
	<td>
		external/picture link (e.g. http://www.site.com or http://www.site.com/picture.jpg):
	</td>
	<td>
		<input type=\"text\" name=\"_link\" size=\"30\" value=\"$link\">
		<a href=\"?node=" . HELP_NODE . "#externallinks\">help</a>
	</td>
</tr>
</table>

<br />
			
<dl>
	<dt><div class=\"subtitle\">Allowed HTML</div>
	Here are all the allowed tags:<br/>
	</dt>
	<dd>
		<tt>&lt;br&gt; &lt;br/&gt; &lt;em&gt; &lt;strong&gt; &lt;quote&gt; &lt;tt&gt; &lt;b&gt;
		&lt;i&gt; &lt;pre&gt; &lt;u&gt; &lt;s&gt; &lt;big&gt; &lt;small&gt; &lt;sup&gt; &lt;sub&gt;
		&lt;span&gt; &lt;dl&gt; &lt;dd&gt; &lt;dt&gt; &lt;ul&gt; &lt;ol&gt; &lt;li&gt;</tt>
	</dd>
	<dt>
	See <a href=\"?node=" . HELP_NODE . "#allowedhtml\">help</a> page for more information on using
	HTML.
	</dt>
</dl>

<br /><br />
		
<input type=\"submit\" name=\"_previewnode\" value=\"preview node!\">
<input type=\"submit\" name=\"_submitnode\" value=\"submit node!\">
	";
	
	if (isset($this->username) || $this->superuser) {
		$html .= "
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<input type=\"submit\" name=\"_deletenode\" value=\"delete node!\">
		";
	}
	
	$html .= "
</div>
</form>

	";

		$this->directives[d_NODE_CONTENT] .= $html;

	}



	/* Creates the user finger query page.
	 *
	 * Args:	$userData (array)		- Associative array of finger query results to format */

	function createFingerPage($userData) {
		
		$email 	   = "";
		$emailLink = "";
		
		if (substr($userData["email"], 0, 7) == "mailto:") {
			$emailLink = $userData["email"];
			$email     = substr($userData["email"], 7, strlen($userData["email"]));
		} else {
			$email     = $userData["email"];
			$emailLink = "mailto:" . $email;
		}
		
		$nodeInterface = new NodeInterface(HOSTNAME, USERNAME, PASSWORD, DB_NAME, NODE_TABLE);
		$nodeInterface->setUsername($userData["username"]);
		$userHome = $nodeInterface->getHomeNode();
		if (is_string($userHome))
			$userHomeHTML = "<em>" . $userData["username"] . 
							"</em>'s <a href=\"?node=$userHome\">home node</a><br />";

		
		$html = "
<dl>
<dt>
	<div class=\"subtitle\">Finger query for <em>" . $userData["username"] . "</em></div>
	<br />
	Created on " . Util::fmtTimestamp($userData["created"]) . ", last login " .
	Util::fmtTimestamp($userData["ts"]) . "<br />
</dt>
<dd>
	<table border=\"0\" cellspacing=\"5\" cellpadding=\"2\">
	<tr>
		<td class=\"light\"><em>email:</em></td>
		<td><a href=\"$emailLink\">$email</a></td>
	</tr>
	<tr>
		<td class=\"light\"><em>website:</em></td>
		<td><a href=\"" . $userData["website"] . "\">" . $userData["website"] . "</a></td>
	</tr>
		<td class=\"light\"><em>profile:</em></td>
		<td>" . $userData["profile"] . "</td>
	</tr>
	</table>
</dd>
</dl>
List <a href=\"?node=" . LIST_NODE . "&_username=" . $userData["username"] . "\">all nodes</a> by 
<em>" . $userData["username"] . "</em><br />
<a href=\"?node=" . LIST_NODE . "&listmode=latest&_username=" . $userData["username"] . 
"\">Latest nodes</a> by <em>" . $userData["username"] . "</em><br />
$userHomeHTML
<dl>
<dt>List <em>" . $userData["username"] . "'s</em>:</dt>
		";
		
		global $NODE_METATYPES;
		
		foreach ($NODE_METATYPES as $nodeMetatype) {
			if ($nodeMetatype != METATYPE_HOME)
				$html .= "<dd><a href=\"?node=" . LIST_NODE . 
						 "&listmode=$nodeMetatype&_username=" . $userData["username"] . 
						 "\">$nodeMetatype nodes</a></dd>\n";
		}

		$this->directives[d_NODE_CONTENT] .= $html;

	}



	/* Creates a node search form.
	 *
	 * Args:	$script 			- Referring script */

	function createSearchForm($script) {
	
		$html = "
<form action=\"$script\" method=\"post\" name=\"submit\">
	search for <input type=\"text\" name=\"_search\"> in all nodes
</form>
	";
	
		$this->directives[d_NODE_CONTENT] .= $html;
	
	}



	/* Creates a who user list page.
	 *
	 * Args:	$userList (array)		- Array of associative arrays of each user's data */

	function createWhoPage($userList) {
		
		$html = "<div class=\"subtitle\">Who query for <em>all users</em></div>
				<br /><br /><table><tr><td>USER</td><td>LOGIN</td></tr>";
		
		foreach ($userList as $userData) {
			$html .= "<tr>
						<td><a href=\"?node=" . FINGER_NODE . "&_username=" . 
							$userData["username"] . "\">" . $userData["username"] . "</a></td>
						<td>" . Util::fmtTimestamp($userData["ts"]);

			if ($userData["superuser"] == 't')
				$html .= " [<a href=\"?node=" . HELP_NODE . "#superuser\">superuser</a>]";

			$html .= "</td></tr>";
		}
		
		$html .= "</table>";
		
		$this->directives[d_NODE_CONTENT] .= $html;

	}



	/* Creates the help page. */
	
	function createHelpPage() {

		$html = "

	<div class=\"subtitle\">What is this all about?</div>
	The <i>lns</i> (<i>L</i>ame <i>N</i>ode <i>S</i>ystem) is intended to be an easy to set up 
	personal homepage and idea repository. It manages the creation and display of <i>nodes</i> so 
	that the owner can add ideas to his or her website with relative ease. Visitors may also leave 
	their own thoughts and add these to a particular node, in a similar way to WWW message boards 
	and guest books. The nodes themselves form a mini-internet (a limited form of the popular 
	website <a href=\"http://www.everything2.com\">Everything2</a>) that interlinks pictures, 
	files and text. 
	<br /><br />
	The <a href=\"http://lns.sf.net\">source code</a> for the <i>lns</i> is licensed under the 
	<a href=\"http://www.gnu.org/copyleft/gpl.html\">GPL</a> and is available from 
	<a href=\"http://www.sf.net\">SourceForge</a>.
	
	 
	<br /><br />
	
	<a name=\"externallinks\">&nbsp;</a>
	<a name=\"submit\">&nbsp;</a>
	<div class=\"subtitle\">Creating nodes</div>
	When creating a node, you need to decide first of all what data it will contain. Nodes can be 
	text, text with a picture or a link to an external site. The most common form of node will 
	probably be just text-based, in which case all you need to do is pick a nodename and enter some
	text into the main textbox (i.e. the big one) and add some links to other nodes within your text
	(see <i>Entering text</i> for more details on linking to other nodes). You may optionally add 
	your name to the node and a contact address (either an email address or a website address). If 
	you so wish, you may enter the URL of a picture into the box at the very bottom of the submit 
	page. When you hit the \"preview\" button, the page will reload with a copy of how your node 
	will look at the top. 
	
	<br /><br />
	
	The third type of node (external links) will be required less frequently. In order to create an 
	external link node, you will need just a nodename and a website link address. This URL is 
	placed in the very bottom text field of the submit page. It's worth remembering that any text 
	entered into the main textbox will <b>not</b> be shown if you specify a website in this field. 
	External link nodes should be used when you wish to reference an external site rather than just
	another node on this website (hint: using the 
	<a href=\"?node=" . SHOW_ALL_NODE . "\">show all nodes</a> feature will give you a list of all 
	the website's nodes). 
	<br /><br />
	<dl>
		<dt>For example, say that I would like to link to the website \"http://www.mysite.com\" 
		somewhere in my node that I am currently creating. The node I'm creating would look 
		something like this:</dt>
		<br />
		<dd><pre>This is my wonderful [node]. In order to understand the rich [genius] I <br />
		displayed here, you'll need to visit [mysite].
		</pre></dd>
		<dt>As you can see, my node contains three links: one to \"node\", one to \"genius\" and one
		to \"mysite\". The first two may well have been created by me previously, but the third is 
		the one I need to link to the web address \"http://www.mysite.com\". Therefore, I create a 
		brand new node, this time with the nodename of \"mysite\". It is in this new node that I 
		actually fill in the nodename and the external link field (with a value of 
		\"http://www.mysite.com\"). Therefore, when we look at the first node we created, and click
		on the link to \"mysite\", we will be successfully redirected to the correct URL.</dt>
	</dl>
	
	<br /><br />
	
	<div class=\"subsubtitle\">Anatomy of a node</div>
	The following diagram shows what an average node looks like (using the <i>default</i> theme; 
	see <i>Selecting themes</i>):
	<br /><br />
	<div align=\"center\"><img src=\"./pixmap/help-diag.png\"></div>
	<br />
	Key to the diagram:
	<ol>
		<li>The node's title. From the <i>node name</i> field.</li>
		<li>A link to another node. This was accomplished by putting \"[grand piano]\" in the 
			textbox.</li>
		<li>The node author. From the <i>your name</i> field. Clicking on this will link to the 
		<i>contact</i> field</li>
		<li>Clicking here allows you to add to the node. Your node will appear at the top of the 
			page if submitted.</li>
	</ol>
	
	<br />
	
	<a name=\"enteringtext\">&nbsp;</a>
	<div class=\"subsubtitle\">Entering text</div>
	<dl>
		<dt>The main textbox will accept plain text input and a limited subset of HTML input. New 
		lines and paragraphs will be detected and converted to HTML by the lns. Most important, of 
		course, is the linking in the text to other nodes. Consider our previous example:</dt>
		<dd><pre>This is my wonderful [node]. In order to understand the rich [genius] I <br />
		displayed here, you'll need to visit [mysite].</pre></dd>
		<dt>Placing the square brackets round particular keywords allows you to link to other 
		nodenames with ease. The link ensures that a particular <i>concept</i> is linked to (e.g. 
		the meaning of \"genius\"), even if the relevant node will have to be filled in later by 
		some other person. Rather than declare links explicity, the <i>lns</i> allows you to leave 
		the hard work for later or for someone else.</dt>
	</dl>
	<dl>
		<dt>If you are new to HTML or do not have any experience using it, you will find that merely
		learning a few simple tags will help you to create a nicely formatted node. HTML tags wrap 
		around text and designate a particular attribute for that text. For example:</dt>
		<dd><pre>I would like &lt;b&gt;this text to be bold&lt;/b&gt;</pre></dd>
		<dt>Produces:</dt>
		<dd><pre>I would like <b>this text to be bold</b></pre></dd>
	</dl>		
	
	<a name=\"allowedhtml\"></a>
	
	For HTML, that is just about all the syntax you'll ever need to know. Try experimenting with the
	following simple tags (using the \"preview\" button):
	<ul>
		<li> Line break: <tt>&lt;br&gt;</tt> (optional; newline characters are detected 
			 automatically)</li>
		<li> Stong, emphasis and underline: <tt>&lt;strong&gt;&lt;/strong&gt;</tt>, 
			 <tt>&lt;em&gt;&lt;/em&gt;</tt> and <tt>&lt;u&gt;&lt;/u&gt;</tt> </li>
		<li> Preformatted text and inline monospaced text: <tt>&lt;pre&gt;&lt;/pre&gt;</tt> 
			 and <tt>&lt;tt&gt;&lt;/tt&gt;</tt> </li>
		<li> Small and big text: <tt>&lt;small&gt;&lt;/small&gt;</tt> and 
			 <tt>&lt;big&gt;&lt;/big&gt;</tt> </li>
		<li> Superscript and subscript: <tt>&lt;sup&gt;&lt;/sup&gt;</tt> and 
			 <tt>&lt;sub&gt;&lt;/sub&gt;</tt> </li>
		<li> Quote: <tt>&lt;quote&gt;&lt;/quote&gt;</tt> </li>
	</ul>
		
	If you're feeling particularly daring:
	<ul>
		<li> Class specification: <tt>&lt;span [class=...]&gt;&lt;/span&gt;</tt><br>
			&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i>The \"class\" is optional. Try these classes: 
			\"<tt>title</tt>\", \"<tt>subtitle</tt>\" and \"<tt>subsubtitle</tt>\".</i> </li>
		<li> Unordered and ordered lists: <br /> <tt>
			 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ul&gt;<br />
			 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;li&gt;...&lt;/li&gt;
			 <br />
			 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;li&gt;...&lt;/li&gt;
			 <br />
			 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
			 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/ul&gt; </tt>
			 <br />
			 and <tt>&lt;ol&gt;&lt;/ol&gt;</tt> 
		</li>
		<li> Indented text: <br /><tt>
		  	 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;dl&gt;<br />
		 	 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;dt&gt;...&lt;/dt&gt;<br />
			 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;dd&gt;...&lt;/dd&gt;
			 <br />
			 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;dt&gt;...&lt;/dt&gt;<br />
			 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;dd&gt;...&lt;/dd&gt;
			 <br />
			 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br />
			 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/dl&gt;</tt>
		</li>
	</ul>

	<a name=\"silentupdate\">&nbsp;</a>
	<div class=\"subsubtitle\">Silent Updates</div>
	If you are logged in, you are allowed to silently edit a node by checking the ``silent update''
	box on the <a href=\"?node=" . SUBMIT_NODE . "\">submit</a> page. This means that the time of
	the last edit will be preserved (i.e. it will not be replaced with the current time). This 
	feature enables you to correct typos, etc. without the node unnecessarily appearing on the
	list of recent nodes. In this way you may only flag major node edits you feel worthy of pushing
	the node up to the top of the recent node listing.

	<br /><br />

	<a name=\"newuser\">&nbsp;</a>
	<a name=\"login\">&nbsp;</a>
	<a name=\"logout\">&nbsp;</a>
	<a name=\"finger\">&nbsp;</a>


	<a name=\"anonymoususers\">&nbsp;</a>
	<div class=\"subtitle\">Anonymous Users</div>

	A node displaying this indicates that the node addition was not created by a user with an 
	account. Since anonymous users can call themselves anything they like (in the ``your name'' 
	field of the <a href=\"?node=" . SUBMIT_NODE . "\">submit form</a>), they could pretend to be 
	writing a node as though they were logged in, effectively spoofing a real user's account. The 
	``Anonymous user'' text merely provides a method of differentiating the two.

	<br /><br />

	
	<a name=\"protectednodes\">&nbsp;</a>
	<div class=\"subtitle\">Protected and hidden nodes</div>
	
	There are three ``security'' types for any given node:
	<ol>
		<li> No protection </li>
		<li> Protected </li>
		<li> Hidden </li>
	</ol>

	<div class=\"subsubtitle\">No protection</div>
	These nodes can be added to by anyone, anonymous or not. Individual owners of each writeup
	may edit their own, but there is nothing to stop anyone else adding to this particular node.
	<br /><br />

	<div class=\"subsubtitle\">Protected</div>
	Only the owner of the node may edit or alter the protection level of this node. For instance,
	the ``home'' node may be protected so that the owner of the site can control what is displayed
	there. Protected nodes may only be created by superusers (i.e. administrators).
	<br /><br />

	<div class=\"subsubtitle\">Hidden</div>
	Hidden nodes, such as the <a href=\"?node=" . SUBMIT_NODE . "\">submit</a> node are never
	editable or listable, even by superusers, as they protect functionality of the lns. This help
	page is classed as a ``hidden'' node.

	<br /><br />


	<a name=\"cookies\">&nbsp;</a>
	<div class=\"subtitle\">Cookies</div>
	The lns uses cookies to store information about your current login session (if any) and your
	current user preferences. There is plenty of excellent information available on the web 
	relating to cookies and how they affect privacy and so on. Take a look at the 
	<a href=\"http://www.epic.org/privacy/internet/cookies/\">Electronic Privacy Information 
	Centre</a> page for more information.

	<br /><br />

	<a name=\"preferences\">&nbsp;</a>
	<div class=\"subtitle\">Preferences</div>
	The <a href=\"?node=" . PREFERENCES_NODE . "\">preferences</a> can be used to set options for 
	both the user account (when you are <a href=\"?node=" . LOGIN_NODE . "\">logged in</a>) and 
	website in general.

	<br /><br />

	<div class=\"subsubtitle\">Site Preferences</div>
	There are several options to choose from in this form:
	<ul>
		<li><a name=\"displayrelatednodes\">Display related nodes</a> --- displays a list of 
			nodes that are linked to by one you are browsing;</li>
		<li><a name=\"displayhomenodes\">Display home nodes</a> --- shows all the home nodes on
			the front page;</li>
		<li><a name=\"displayrecentnodes\">Display recent nodes</a> --- shows the recent nodes
			on the front page; and</li>
		<li><a name=\"shownodesinsubmit\">Show existing nodes on submit page</a> --- displays
			all the other writeups for the node you are adding to.
	</ul>
	
	<div class=\"subsubtitle\">Personal Preferences</div>
	This form allows you to set profile information. When a user is ``fingered'', this information
	(email address, website address and profile) is displayed.
	
		";

		$this->directives[d_NODE_CONTENT] .= $html;
	
	}


	
	/* Creates the website preferences form. 
	 * 
	 * Args:	$script (string)		- The referring script 
	 *			$currTheme			    	
	 *				... $lastNodes 		- The preferences for the site */

	function createSitePrefsForm($script, 
							 	 $currTheme, 
							 	 $showRelatedNodes, 
							 	 $showHomeNodes, 
							 	 $showRecentNodes, 
							  	 $showNodesInSubmit,
							 	 $lastNodes) {

		$handle 	= opendir(THEME_PATH); 
		$themedir	= getcwd() . "/" . THEME_PATH;
		$options 	= "";
		
		// Read the directory
		while ($file = readdir($handle)) { 
			// Make sure the filename is a valid directory
			if (is_dir($themedir."/".$file) && $file != "." && $file != "..") {
				$selected = "";
				if ($currTheme == $file)
					$selected = " selected";
        		$options .= "<option value=\"$file\"$selected>$file\n"; 
			} 
		}
		closedir($handle);

		$relatedChecked  = "";
		$homeChecked	 = "";
		$recentChecked	 = "";
		$existingChecked = "";
		
		if ($showRelatedNodes)  $relatedChecked  = " checked";
		if ($showHomeNodes)	    $homeChecked	 = " checked";
		if ($showRecentNodes)   $recentChecked   = " checked";
		if ($showNodesInSubmit) $existingChecked = " checked";

		$html = "
<div class=\"subtitle\">Site Preferences</div>
Select your preferences for this website from the following options 
(<span class=\"warning\">requires <a href=\"?node=". HELP_NODE . "#cookies\">cookies</a></span>):
<br /><br />

<form action = \"$script\" method=\"post\" name=\"_siteprefs\">
	<table>
	<tr>
		<td>display related nodes:</td>
		<td><input type=\"checkbox\" name=\"_relatednodes\"$relatedChecked></td>
	</tr>
	<tr>
		<td>display home nodes:</td>
		<td><input type=\"checkbox\" name=\"_homenodes\"$homeChecked></td>
	</tr>
	<tr>
		<td>display recent nodes:</td> 
		<td><input type=\"checkbox\" name=\"_recentnodes\"$recentChecked></td>
	</tr>
	<tr>
		<td>show existing nodes on submit page:</td>
		<td><input type=\"checkbox\" name=\"_nodesinsubmit\"$existingChecked>
		<a href=\"?node=" . HELP_NODE . "#shownodesinsubmit\">help</a></td>
	</tr>
	</table>
	
	show the last <input type=\"text\" size=\"5\" value=\"$lastNodes\"
						 name=\"_lastnodes\"> nodes on the front page<br />
	<br />
	select theme:
	<select name=\"_theme\">
		$options
	</select>
	<br /><br /><br />
	<input type=\"submit\" name=\"_savesiteprefs\" value=\"save site prefs\">
</form>
		";

		$this->directives[d_NODE_CONTENT] .= $html;
	}



	/* Creates the personal (user) preferences form.
	 *
	 * Args: 	$script (string)		- The referring script
	 *			$email
	 *				... $profile		- Attributes for a user */

	function createUserPrefsForm($script, $email, $website, $profile) {
	
		$html = "
<div class=\"subtitle\">Personal Preferences</div>
Set your personal preferences using the following input boxes 
(<span class=\"warning\">requires <a href=\"?node=" . HELP_NODE . "#cookies\">cookies</a></span>):

<br /><br />

<form action = \"$script\" method=\"post\" name=\"_personalprefs\">
	<table border=\"0\">
	<tr>
		<td>current password:</td>
		<td><input type=\"password\" name=\"_currpassword\" size=\"20\"></td>
	</tr>
	</tr>
		<td>new password:</td>
		<td><input type=\"password\" name=\"_newpassword\" size=\"20\"> (must be >= " .
		GEN_PASSWORD_MIN . " characters long)</td>
	</tr>
	<tr>
		<td>email address:</td>
		<td><input type=\"text\" name=\"_email\" value=\"$email\" size=\"30\"></td>
	</tr>
	<tr>
		<td>website:</td>
		<td><input type=\"text\" name=\"_website\" value=\"$website\" size=\"40\"></td>
	</tr>
	</table>

	profile:
	<div align=\"left\">
		<textarea cols=\"45\" rows=\"10\" name=\"_profile\" wrap=\"virtual\">$profile</textarea>
	</div>
	<br /><br />
	<input type=\"submit\" name=\"_savepersonalprefs\" value=\"save personal prefs\">
</form>
		";

		$this->directives[d_NODE_CONTENT] .= $html;

	}



	/* Creates the form for registering a new user.
	 *
	 * Args:	$script (string)		- The referring script */

	function createNewUserForm($script) {

		$html = "

<form action=\"$script\" method=\"post\" name=\"newuser\">
	Create your username with the form below (user accounts <span class=\"warning\">require 
	<a href=\"?node=" . HELP_NODE . "#cookies\">cookies</a></span>):
	<br /><br />
	username: <input type=\"text\" name=\"_username\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
	<br /><br />
	<input type=\"submit\" name=\"_newuser\" value=\"register\">
</form>


	";
		$this->directives[d_NODE_CONTENT] .= $html;
		
	}



	/* Creates the form for logging a user in.
	 *
	 * Args:	$script (string)		- The referring script */

	function createLoginForm($script) {

		$html = "
Please enter your authentication details in the following form (<span class=\"warning\">requires 
<a href=\"?node=" . HELP_NODE . "#cookies\">cookies</a></span>):<br /><br />

<form action=\"$script\" method=\"post\" name=\"login\">
	username: <input type=\"text\" name=\"_username\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
	password: <input type=\"password\" name=\"_password\">
	&nbsp;&nbsp;&nbsp;&nbsp;<input type=\"submit\" name=\"_login\" value=\"login\">
</form>
<br />
		";
		
		$this->directives[d_NODE_CONTENT] .= $html;
	}



	/* Creates the form for logging a user out.
	 *
	 * Args:	$script (string)		- The referring script */

	function createLogoutForm($script) {

		$html = "
<form action=\"$script\" method=\"post\" name=\"logout\">
	Click the logout button to finish your session:&nbsp;&nbsp;&nbsp;&nbsp;
	<input type=\"submit\" name=\"_logout\" value=\"logout\">
</form>
<br />
	";
		$this->directives[d_NODE_CONTENT] .= $html;
		
	}



} // End class HTMLFactory


?>

Return current item: Lame Node System