SELECT id, parent_id, title, link, position FROM menu_item ORDER BY parent_id, position;
$html = ''; $parent = 0; $parent_stack = array(); // $items contains the results of the SQL query $children = array(); foreach ( $items as $item ) $children[$item['parent_id']][] = $item; while ( ( $option = each( $children[$parent] ) ) || ( $parent > 0 ) ) { if ( !empty( $option ) ) { // 1) The item contains children: // store current parent in the stack, and update current parent if ( !empty( $children[$option['value']['id']] ) ) { $html .= '<li>' . $option['value']['title'] . '</li>'; $html .= '<ul>'; array_push( $parent_stack, $parent ); $parent = $option['value']['id']; } // 2) The item does not contain children else $html .= '<li>' . $option['value']['title'] . '</li>'; } // 3) Current parent has no more children: // jump back to the previous menu level else { $html .= '</ul>'; $parent = array_pop( $parent_stack ); } } // At this point, the HTML is already built echo $html;