/    Sign up×
Community /Pin to ProfileBookmark

Dynamically generated menu (un-ordered list)

Hi There guys. I’ve got a bit of a nippy one here and would just like peoples opinions on the best way to do this (to avoid headaches).

I have been following a [URL=http://www.intranetjournal.com/articles/200412/ij_12_08_04a.html]CMS creation tutorial[/URL] and have now finished so I’m expanding it a bit.
The database is set up so that an articles foreign key is the primery key of the section that it belongs to.

The problem I am having is trying to create a symantically correct menu of the sections due to the fact that each section can have a parent.

The section table schema is as follows cmssections([U]ID[/U], name, [I]parentid[/I]).
I would like to create a list along these lines.

[code=html]<ul>
<li>Section1</li>
<li>Section2
<ul>
<li>Subsection1</li>
<li>Subsection2
<ul>
<li>Subsubsection1</li>
</ul>
</li>
</ul>
</li>
<li>Section3</li>
</ul>[/code]

I searched the forum for an answer and although there were quite a few relating to dynamically created menus, none really were relevant.

Can people give me their views on what would be the best way to create a loop which would create a list as above?

I was thinking of adding a column into the table, “has_children” and then if a row “has_children” then php would execute a query looking for all sections with that parent.

I hope this makes sense. If anyone has any ideas on how I could do this in a more efficient way please do say so. I would be happy to hear all suggestions.
Thanks
Graham

to post a comment
PHP

11 Comments(s)

Copy linkTweet thisAlerts:
@DoppleauthorNov 14.2006 — Rigth What I have so far is below although (schoolboy error) I'm getting a parse error on line 75 "while($subrow = $connector->fetchArray($subresult)){"

I've looked over it but cannot see where the error lies. Can anyone through any light on this and/or advise if they think this is the correct way to go?

[code=php]echo '<ul>';
$result = $connector->query('SELECT ID,name,parentid FROM cmssections');

// Get an array containing the results.
// Loop for each item in that array
while ($row = $connector->fetchArray($result)){
if($row['has_children'] = '1'){
echo '<li>' . $row['name'] . ' - ';
echo '<a href="editSections.php?action=delete&id=' . $row['ID'] . '">Delete</a>';
echo '<ul>';
$subresult = $connector->query('SELECT ID,name,parentid FROM cmssections WHERE parentid = ' . $row['ID'] .');
while($subrow = $connector->fetchArray($subresult)){
echo '<li>' . $subrow['name'] . ' - ';
echo '<a href="editSections.php?action=delete&id=' . $subrow['ID'] . '">Delete</a></li>';
}
echo '</ul>';
echo '</li>';
} else {
// Show the name of section
echo '<li>' . $row['name'] . ' - ';
// Show the delete link
echo '<a href="editSections.php?action=delete&id=' . $row['ID'] . '">Delete</a></li>';
}
}
echo '</ul>';[/code]
Copy linkTweet thisAlerts:
@scousesheriffNov 14.2006 — Presuming that the top level sections have a blank parentID, you could use a recursive loop
[code=php]
<?php
//function to get the section names, and recursively all it's children
function GetSections($Parent){
$result = mysql_query("select ID, name from cmssections where parentid = '".$Parent);
echo "<ul>";
while($row = mysql_fetch_array($result)){
echo "<li>".$row['name'];
GetSections($row['ID']);
echo "</li>";
}
echo "</ul>";
}
//Then simply call GetSections with a blank value to get the top level sections and then build the entire menu.
GetSections('');
?>
[/code]

will be worth including some checking to make sure that there are some results etc, but this should get you started.
Copy linkTweet thisAlerts:
@DoppleauthorNov 14.2006 — I found the error after looking at my post.
[code=php]$subresult = $connector->query('SELECT ID,name,parentid FROM cmssections WHERE parentid = ' . $row['ID']); [/code]
That's the problem with plain text editors. You can't see any formatting.

The only problem I can see with this is what would I do if there was more than 2 generations (1 paretn and 1 child). The code works but I just don't see it as being the best way to do this.
Copy linkTweet thisAlerts:
@DoppleauthorNov 14.2006 — Thanks Scousesheriff. I'll try that out.
Copy linkTweet thisAlerts:
@DoppleauthorNov 14.2006 — Thanks Scousesheriff. That's worked a treat. That'll also work well for the forum I'm making.

Much appreciated.

Regards

Graham
Copy linkTweet thisAlerts:
@aj_nscNov 14.2006 — dopple, I recently spent a couple of nights working on the exact same thing using php and a mysql database although my table structure looked a little different than yours....I then used hashes and foreach loops to generate a perfect unordered html menu which validates when sent to the XHTML validator. If you're having problems and wouldn't mind creating one from scratch (its not hard because I have the table structure and the code) then drop me a line and I'll hand it over.

[email][email protected][/email]
Copy linkTweet thisAlerts:
@DoppleauthorNov 15.2006 — Ok what I have so far is as follows
[code=php]<?php

function listSections($parent){
$connector = new DbConnector();
$result = $connector->query('SELECT ID, name from cmssections where parentid = ' . $parent);
echo "<ul>n";
while($row = $connector->fetchArray($result)){

echo '<li><a href="section.php?id=' . $row['ID'] . '">' . $row['name'] . '</a>' . "n";
listSections($row['ID']);
echo "</li>n";

}
echo "</ul>n";
}

function showSections(){
echo "n<h2>Sections</h2>n";
listSections('0');
}

?>[/code]


The only problem being that it inserts a couple of empty <ul></ul> tags after the bottom level branches. See below (I've indented the code to make it a bit more understandable).

How would I stop the 2 empty list tags being outputted?

[code=html]<ul>
<li><a href="section.php?id=1">News</a>
<ul>
<li><a href="section.php?id=8">Tumbleweed</a>
<ul>
</ul>
</li>
</ul>
</li>
<li><a href="section.php?id=2">Cabbages</a>
<ul>
</ul>
</li>
<li><a href="section.php?id=3">Crazy Pies</a>
<ul>
<li><a href="section.php?id=4">Don Corleone</a>
<ul>
<li><a href="section.php?id=5">Lazy Eyes</a>
<ul>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="section.php?id=6">Pork Chop Sandwiches</a>
<ul>
</ul>
</li>
</ul>[/code]


Thanks a lot

Graham
Copy linkTweet thisAlerts:
@scragarNov 15.2006 — [code=php]<?php

function listSections($parent){
$connector = new DbConnector();
$result = $connector->query('SELECT ID, name from cmssections where parentid = ' . $parent);
if(mysql_num_rows($result)){
echo "<ul>n";
};
while($row = $connector->fetchArray($result)){

echo '<li><a href="section.php?id=' . $row['ID'] . '">' . $row['name'] . '</a>' . "n";
listSections($row['ID']);
echo "</li>n";

}
if(mysql_num_rows($result)){
echo "</ul>n";
};
}

function showSections(){
echo "n<h2>Sections</h2>n";
listSections('0');
}

?>[/code]
my hack should work(simply check if there are any childs before echoing out the <ul> and closing </ul>) if it doesn't let me know and I'll take a closer look.
Copy linkTweet thisAlerts:
@scousesheriffNov 15.2006 — Slightly more efficient to have less tests of mysql_num_rows:
[code=php]
if(mysql_num_rows($result)){
echo "<ul>n";
while($row = $connector->fetchArray($result)){
echo '<li><a href="section.php?id=' . $row['ID'] . '">' . $row['name'] . '</a>' . "n";
listSections($row['ID']);
echo "</li>n";
}
echo "</ul>n";
}
[/code]
Copy linkTweet thisAlerts:
@DoppleauthorNov 20.2006 — Slightly more efficient to have less tests of mysql_num_rows:
[code=php]
if(mysql_num_rows($result)){
echo "<ul>n";
while($row = $connector->fetchArray($result)){
echo '<li><a href="section.php?id=' . $row['ID'] . '">' . $row['name'] . '</a>' . "n";
listSections($row['ID']);
echo "</li>n";
}
echo "</ul>n";
}
[/code]
[/QUOTE]

Thanks Scousesheriff. That's done the trick.

Bokeh, I like what you did with the tree view menu. Right now I am focusing purely on content and once the functional side of the site is complete, THEN I will be working on the CSS. A long was to gio but I have bookmarked your site to give me some Ideas for when I come to the styles.
×

Success!

Help @Dopple spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.24,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...