BLiu1's Blog

Sitemap and New Menu System

August 9, 2014
Edited

You may have noticed that the menu, list on "/pages/", and the sitemap contain similar items. Being the "lazy developer" I am, I have decided to create a system in which I would only have to update a single file to keep the links in these three places updated.

Using XML as my "database", I created an editable tree of links around my website, a.k.a. a sitemap. I used the SimpleXML XML Parser in native PHP to access and parse the XML and a few functions to arrange it into HTML and echo it. I used XML because I felt experimental and also to avoid the hassles of SQL databases. Here's the XML source.

<?xml version="1.0" encoding="UTF-8"?>
<sitemap name="">
	<dir name="pages">
		<dir name="efi2" title="Escape from Isolation 2">
			<page>index.php</page>
		</dir>
		<dir name="avoider" title="Avoider Game">
			<page>index.php</page>
		</dir>
		<dir name="edit" title="Text Edit">
			<page>index.php</page>
		</dir>
		<dir name="bsod" title="Fake Blue Screen">
			<page>index.php</page>
			<page>stoperror.php</page>
		</dir>
		<dir name="overmouse" title="Overmouse">
			<page>index.php</page>
		</dir>
		<dir name="nothing" title="Invisible Nothing">
			<page>index.php</page>
		</dir>
		<page>index.php</page>
	</dir>
	<dir name="blog">
		<page>index.php</page>
		<page>viewpost.php?id=1</page>
		<page>viewpost.php?id=2</page>
		<page>viewpost.php?id=3</page>
		<page>viewpost.php?id=4</page>
		<page>viewpost.php?id=5</page>
		<page>viewpost.php?id=6</page>
		<page>viewpost.php?id=7</page>
		<page>tags.php</page>
	</dir>
	<page>index.php</page>
	<page>about.php</page>
	<page>contact.php</page>
	<page>license.php</page>
	<page>sitemap.php</page>
</sitemap>

Notice the difference between the directory name and the title (which is the name of the link in pages).

In the sitemap.php file, the following PHP arranges and echoes the sitemap.

<?php
$sitemap = simplexml_load_file('./custom-sitemap.xml');
function print_sitemap($sitemap) {
	$output = "";
	$output .= print_dirs($sitemap, $sitemap);
	$output .= print_pages($sitemap, $sitemap);
	echo $output;
}
function print_dirs($sitemap, $parent){
	$output = "";
	foreach($parent->dir as $dir) {
		$path = find_path($parent);
		$output .= '<li><a href="/' . $path . $dir['name'] . '/">' . $dir['name'] . '/</a><ul>';
		$output .= print_dirs($sitemap, $dir);
		$output .= print_pages($sitemap, $dir);
		$output .= '</ul></li>';
	}
	return $output;
}
function print_pages($sitemap, $dir){
	$output = "";
	foreach($dir->page as $page) {
		if(((string) $page !== 'index.html') && ((string) $page !== 'index.php')) {
			$path = find_path($dir);
			$output .= '<li><a href="/' . $path . $page . '">' . $page . '</a></li>';
		}
	}
	return $output;
}
function find_path($parent) {
	$path='';
	while((string)$parent['name']) {
		$path = (string)$parent['name'] . '/' . $path;
		$xpath = $parent->xpath("parent::*");
		$parent = $xpath[0];
	}
	return $path;
}
/* I realized much later that instead of using a recursive function and a whole bunch of other functions, I could've just used a while loop. *facepalm* */
/* However, the functions have more semantic meaning. */
/* Actually, I think using functions was the better way to do it. */
?>

Later on in the HTML, I have the function call as follows. <?php print_sitemap($sitemap); ?>

Interesting Fact: The print_dirs function is the first recursive function I have ever written! It took some thinking to wrap my brain around the problem of directories and sub-directories and come up with that.

Lastly, here is the source to the (included) menu.php.

<?php
function pages($path = "./") {
	$sitemap = simplexml_load_file($path . 'custom-sitemap.xml');
	foreach($sitemap->dir[0]->dir as $page) {
		echo '		<li><a href="/pages/' . $page['name'] . '/">' . $page['title'] . '</a></li>' . "\n";
	}
}
?>
<!-- Navigation Menu -->
<nav>
	<ul>
	<li><a href="/">Home</a></li>
	<li><a href="/about.php">About</a></li>
	<li id="pages" class=""><a href="/pages/">Pages</a>
		<ul>
<?php
if (file_exists("./custom-sitemap.xml")) {
    pages();
} elseif (file_exists("../custom-sitemap.xml")) {
    pages("../");
}
?>
		</ul>
	</li>
	<li><a href="/blog/">Blog</a></li>
	<li><a href="/contact.php">Contact</a></li>
	</ul>
</nav>
<script>/* Nav JS */c=document.getElementById("pages");c.firstElementChild.href="javascript:void(0);";c.onclick=function(){""===c.className?c.className="drop":c.className=""};</script>
<!-- End Navigation Menu -->

The pages function echoes the contents of the pages directory. The $path parameter is a workaround due to the fact that the menu is included from webpages at the root and the index.php file on the pages directory.

Tags:

Comments

BLiu1's Blog - Sitemap and New Menu System

comments powered by Disqus
eXTReMe Tracker