Re: Array to HTML List
| From: | David Harkness | Date: | Thu, 31 Mar 2016 15:30:08 +0000 |
| Subject: | Re: Array to HTML List | ||
| References: | 1 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-325518@lists.php.net to get a copy of this message | ||
On Tue, Mar 29, 2016 at 9:24 PM, Kevin Waterson <kevin.waterson@gmail.com>
wrote:
> I need to get an array of data (comments) into a threaded HTML list.
>
Quick question: are you sure you want to put the replies into a <ul> inside
an <li> rather than a <ul> *inside* the parent comment's <li>? Putting them
into their own <li> sibling to the parent comment makes them seem to apply
to their parent's parent.
Not too sure how to go about this one.
>
> Maybe I need to build up some sort of tree and traverse it.
>
> http://pastie.org/10778741
Navigating a tree structure (technically a forest) where
- the root array holds all top-level comments as subtrees,
- each node is a comment, and
- each node's children are its comment's direct replies
will be easier than using the raw array. A depth-first traversal will give
you the perfect points at which to take action:
- Start: Output "<ul>"
- Visit node: output "<li>$comment</li>"
- Visit children: output "<li><ul>"; visit each child; output
"</ul></li>"
- End: output "</ul>"
Luckily, your path value makes building this tree easy.
$threads = [];
foreach ($comments as $comment) {
$replies = &$threads;
$ids = explode(',', trim($comment['path'], '{}'));
$commentId = array_pop($ids);
if ($ids) {
foreach ($ids as $id) {
if (!isset($replies[$id])) {
$replies[$id] = ['comment' => null, 'replies' => []];
}
$replies = &$replies[$id]['replies'];
}
}
$replies[$commentId] = ['comment' => $comment, 'replies' => []];
}
And here's how you can output it:
echo "<ul>\n";
foreach ($threads as $thread) {
outputThread($thread);
}
echo "</ul>\n";
function outputThread($thread) {
echo "<li>{$thread['comment']['content']}</li>\n";
if ($thread['replies']) {
echo "<li><ul>\n";
foreach ($thread['replies'] as $reply) {
outputThread($reply);
}
echo "</ul></li>\n";
}
}
Which results in (after running through HTMLTidy):
<ul>
<li>Lost my heart and a leg in Australia</li>
<li>
<ul>
<li>I left my heart in sandcrabs bistro</li>
<li>
<ul>
<li>I left my heart in San Francisco</li>
<li>
<ul>
<li>That is the worst joke ever.</li>
<li>Worst joke evar.</li>
</ul>
</li>
<li>What happened to mudcrab?</li>
</ul>
</li>
<li>I am the tinman, and have no heart</li>
</ul>
</li>
<li>Even on land there are loan sharks</li>
</ul>
All in one: http://pastie.org/10780881
Cheers!
David