I am trying to build a dynamically generated unordered list in the following format using PHP. I am using CodeIgniter but it can just be normal php.
This is the end output I need to achieve.
<ul id="categories" class="menu">
<li rel="1">
Arts & Humanities
<ul>
<li rel="2">
Photography
<ul>
<li rel="3">
3D
</li>
<li rel="4">
Digital
</li>
</ul>
</li>
<li rel="5">
History
</li>
<li rel="6">
Literature
</li>
</ul>
</li>
<li rel="7">
Business & Economy
</li>
<li rel="8">
Computers & Internet
</li>
<li rel="9">
Education
</li>
<li rel="11">
Entertainment
<ul>
<li rel="12">
Movies
</li>
<li rel="13">
TV Shows
</li>
<li rel="14">
Music
</li>
<li rel="15">
Humor
</li>
</ul>
</li>
<li rel="10">
Health
</li>
And here is my SQL that I have to work with.
--
-- Table structure for table `categories`
--
CREATE TABLE IF NOT EXISTS `categories` (
`id` mediumint(8) NOT NULL auto_increment,
`dd_id` mediumint(8) NOT NULL,
`parent_id` mediumint(8) NOT NULL,
`cat_name` varchar(256) NOT NULL,
`cat_order` smallint(4) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
So I know that I am going to need at least 1 foreach loop to generate the first level of categories.
What I don't know is how to iterate inside each loop and check for parents and do that in a dynamic way so that there could be an endless tree of children.
Thanks for any help you can offer.
Tim
If you're outputting every category, then I'd probably do it in two steps:
First, grab all the relevant data from the database
$items = array();
$res = mysql_query(...);
while ($row = mysql_fetch_assoc($res)) {
$items[$row['parent_id']][] = $row;
}
Then you have all your items grouped by their parent. You can then use a recursive function to process them all:
function showMenu($items, $parent = null) {
// Assuming root elements have parent_id of 0:
$index = $parent == null ? '0' : $parent;
if (empty($items[$index])) {
// No children, don't output anything
return;
}
echo '<ul', $parent == null ? ' id="categories" ... ' : '', '>';
foreach ($items[$index] as $child) {
echo '<li rel="', $child['id'], '">', htmlentities($child['cat_name']);
showMenu($items, $child['id']);
echo '</li>';
}
echo '</ul>';
}
showMenu($items);
The function is recursively called for each item in the menu, and checks to see if that item has any children. If it does, it prints out the relevant <li/>
entries and calls itself again to print out the children of that item.