Page 1 of 1

Building a nested UL from linear array

Posted: Tue Dec 15, 2009 10:13 pm
by alex.barylski
Please Note: In case you don't read the sitepoint.com thread I have one minor requiement other than producing validating, semantically correct code. I cannot use recursion or classes/methods or anything which cannnot be easily expressed in a template layer (Smarty, Dummy, PHP alternative Syntax, etc). The array is fed to the template layer as a linear array and nesting must be determined by the 'depth' value of each element in the array. Which is what is complicating this issue for me.

I asked this on SitePoint.com (http://www.sitepoint.com/forums/showthr ... ?p=4459661) and received a few replies. Almost have it working but not validating or validating but semantically incorrect, etc. Figured I'd post here and see if someone could spot the missing conditionals:

Code: Select all

<?php
$items = array(
    array(
        'link_id' => 1,
        'root_id' => 0,
        'label' => 'Home',
        'depth' => 0
    ),
    array(
        'link_id' => 33,
        'root_id' => 1,
        'label' => 'About PCSpectra',
        'depth' => 1
    ),
    array(
        'link_id' => 36,
        'root_id' => 33,
        'label' => 'sub-sub-children item',
        'depth' => 2
    ),
    array(
        'link_id' => 2,
        'root_id' => 0,
        'label' => 'SitePoint.com',
        'depth' => 0
    ),
    array(
        'link_id' => 3,
        'root_id' => 0,
        'label' => 'Solutions',
        'depth' => 0
    ),
    array(
        'link_id' => 34,
        'root_id' => 3,
        'label' => 'Bronze',
        'depth' => 1
    ),
    array(
        'link_id' => 35,
        'root_id' => 3,
        'label' => 'Silver',
        'depth' => 1
    )
);
class SomeClass
{
    private $items = array();
    
    function __construct($items)
    {
        $this->items = $items;
    }
    function listItems()
    {
        $html = '';
 
        $depth = 0; 
        foreach($this->items as $index => $item){ 
            $newDepth = intval($item['depth']);
            if ($newDepth > $depth) {
                while ($newDepth > $depth) {
                    $html .= '<ul><li>';
                    $depth++;
                 }
            } else if ($newDepth < $depth) { 
                while ($newDepth < $depth) {
                    $html .= '</li></ul>';
                    $depth--;
                } 
            } else if ($newDepth === $depth) {
                if ($index === 0) {
                    $html .= '<ul><li>';
                } else {
                    $html .= '</li><li>'; 
                }
            }
            
            $html .= htmlentities($item['label']);
            $depth = $newDepth;
        }
        if (count($this->items) > 0) {
            while ($depth-- >= 0) {
                $html .= '</li></ul>';
            }
        }
        echo $html; 
    }
}
$someClass = new SomeClass($items);
$someClass->listItems();
Any ideas?

Cheers,
Alex

Re: Building a nested UL from linear array

Posted: Wed Dec 16, 2009 10:19 am
by alex.barylski
Bump: Where the heck is feyd when you need him, he was always helpful to me with this kind of sutff :)