PHP Class: PageTree
May 16th, 2009
Around a year ago now, when I was working at Active Webdezign, I built a small CMS for a website, no more that 5 pages to it. One thing I was thinking of back then was the ability to create a system where you could have a single table for all pages, but have the ability to havarte parent and child pages without the need to create another table. Basically like WordPress does it. And at the time, I knew that I would probably be using recursion, but when I started trying to plan it out, I was at a complete loss. I just couldn’t get my head round the necessary components to the system. But now I think I’ve done it.
It’s a fairly primitive system I imagine, but I’ve tried to add some interesting functionality to it, based on what I’ve needed in the last few projects. Two of the most important features to me were 1) the format stays as simple as possible and 2) the array of pages does not have to be in order, so by that I mean if later on you decide that you move an older page to be a child page of a newer page, you don’t have to change the id or timestamp to do so.
It basically works like this: you pass an array of arrays with information on the page in a specific format shown below.
$pages = array( array(0,'Home',-1,'#',1), array(2,'Blog',-1,'#',1), array(3,'Project 1',1,'#',1), array(4,'Project 2',1,'#',1), array(1,'Work',-1,'#',1), array(5,'Blog Post 1',2,'#',1), array(6,'Contact',-1,'#',1), array(7,'Sub test',5,'#',1) ); /* array element key: page_id | name | page_parent | link | show */ $test = new PageTree($pages); $test->show();
And this gives the following HTML out when you call the show() method:
<ul> <li><a class="page_0" href="#" title="View 'Home'">Home</a></li> <li><a class="page_2" href="#" title="View 'Blog'">Blog</a> <ul> <li><a class="page_5" href="#" title="View 'Blog Post 1'">Blog Post 1</a> <ul> <li><a class="page_7" href="#" title="View 'Sub test'">Sub test</a></li> </ul> </li> </ul> </li> <li><a class="page_1" href="#" title="View 'Work'">Work</a> <ul> <li><a class="page_3" href="#" title="View 'Project 1'">Project 1</a></li> <li><a class="page_4" href="#" title="View 'Project 2'">Project 2</a>/li> </ul> </li> <li><a class="page_6" href="#" title="View 'Contact'">Contact</a></li> </ul>
NB: I did try to tab out the HTML, but WordPress has a nasty knack of wiping it when I switched between the RTE and plain HTML views. Here’s the generated list as it would look on screen:
As I said before, the order of the array you give the function is irrelevant. Work‘s subpages are positioned before the page itself in the array, but when the list is generated, it all falls into place.
Why?
This was basically a test for myself, having learnt a few new things on my course this year about general programming. But at the same time, knowing that I’ll be building bigger systems with my job with University of Kent web team next term, this might turn out to be a pretty useful tool. After all, I’ve still got the humility to admit I’m still a relative novice, and one has to keep striving to learn and try new things.
For all those interested, you can download the source for the class here:
Download PHP Class: PageTree v0.1
I may opt for some more improvements, one of which might be to change the loop structure. According to PHP Bench, the foreach loop is almost 6 times as slow as sizeof then for, and seeing as this is a recursive function using a couple of foreach loops, that might be a good idea.