0, 'show_date' => '', 'date_format' => get_option('date_format'),
'child_of' => 0, 'exclude' => '', 'title_li' => __('Pages'), 'echo' => 1, 'authors' => '', 'sort_column' => 'menu_order');
$r = array_merge($defaults, $r);
$output = '';
$current_page = 0;
// sanitize, mostly to keep spaces out
$r['exclude'] = preg_replace('[^0-9,]', '', $r['exclude']);
// Allow plugins to filter an array of excluded pages
$r['exclude'] = implode(',', apply_filters('wp_list_pages_excludes', explode(',', $r['exclude'])));
// Query pages.
$pages = get_pages($r);
if ( !empty($pages) ) {
if ( $r['title_li'] )
$output .= '
' . $r['title_li'] . '
';
global $wp_query;
if ( is_page() )
$current_page = $wp_query->get_queried_object_id();
$output .= iwalk_page_tree($pages, $r['depth'], $current_page, $r);
if ( $r['title_li'] )
$output .= '
';
}
$output = apply_filters('ideas_list_pages', $output);
if ( $r['echo'] )
echo $output;
else
return $output;
}
function iwalk_page_tree() {
$walker = new iWalker_Page;
$args = func_get_args();
return call_user_func_array(array(&$walker, 'iwalk'), $args);
}
class iWalker {
var $tree_type;
var $db_fields;
//abstract callbacks
function istart_lvl($output) { return $output; }
function iend_lvl($output) { return $output; }
function istart_el($output) { return $output; }
function iend_el($output) { return $output; }
function iparent_start($output) { return $output; }
function iparent_end($output) { return $output; }
function iwalk($elements, $to_depth) {
$args = array_slice(func_get_args(), 2); $parents = array(); $depth = 1; $previous_element = ''; $output = '';
//padding at the end
$last_element->post_parent = 0;
$last_element->post_id = 0;
$elements[] = $last_element;
$id_field = $this->db_fields['id'];
$parent_field = $this->db_fields['parent'];
$flat = ($to_depth == -1) ? true : false;
$top_level = ($depth == 1) ? true : false;
foreach ( $elements as $element ) {
// If flat, start and end the element and skip the level checks.
if ( $flat) {
// Start the element.
if ( isset($element->$id_field) && $element->$id_field != 0 ) {
$cb_args = array_merge( array($output, $element, $depth - 1), $args);
$output = call_user_func_array(array(&$this, 'istart_el'), $cb_args);
}
// End the element.
if ( isset($element->$id_field) && $element->$id_field != 0 ) {
$cb_args = array_merge( array($output, $element, $depth - 1), $args);
$output = call_user_func_array(array(&$this, 'iend_el'), $cb_args);
}
continue;
}
// Walk the tree.
if ( !empty($previous_element) && ($element->$parent_field == $previous_element->$id_field) ) {
// Previous element is my parent. Descend a level.
array_unshift($parents, $previous_element);
if ( !$to_depth || ($depth < $to_depth) ) { //only descend if we're below $to_depth
$cb_args = array_merge( array($output, $depth), $args);
$output = call_user_func_array(array(&$this, 'istart_lvl'), $cb_args);
} else if ( $to_depth && $depth == $to_depth ) { // If we've reached depth, end the previous element.
$cb_args = array_merge( array($output, $previous_element, $depth), $args);
$output = call_user_func_array(array(&$this, 'iend_el'), $cb_args);
}
$depth++; //always do this so when we start the element further down, we know where we are
} else if ( $element->$parent_field == $previous_element->$parent_field) {
// On the same level as previous element.
if ( !$to_depth || ($depth <= $to_depth) ) {
$cb_args = array_merge( array($output, $previous_element, $depth - 1), $args);
$output = call_user_func_array(array(&$this, 'iend_el'), $cb_args);
}
} else if ( $depth > 1 ) {
// Ascend one or more levels.
if ( !$to_depth || ($depth <= $to_depth) ) {
$cb_args = array_merge( array($output, $previous_element, $depth - 1), $args);
$output = call_user_func_array(array(&$this, 'iend_el'), $cb_args);
}
while ( $parent = array_shift($parents) ) {
$depth--;
if ( !$to_depth || ($depth < $to_depth) ) {
$cb_args = array_merge( array($output, $depth), $args);
$output = call_user_func_array(array(&$this, 'iend_lvl'), $cb_args);
$cb_args = array_merge( array($output, $parent, $depth - 1), $args);
$output = call_user_func_array(array(&$this, 'iend_el'), $cb_args);
}
if ( $element->$parent_field == $parents[0]->$id_field ) {
break;
}
}
} else if ( !empty($previous_element) ) {
// Close off previous element.
if ( !$to_depth || ($depth <= $to_depth) ) {
$cb_args = array_merge( array($output, $previous_element, $depth - 1), $args);
$output = call_user_func_array(array(&$this, 'iend_el'), $cb_args);
}
}
// Start the element.
if ( !$to_depth || ($depth <= $to_depth) ) {
if ( $element->$id_field != 0 ) {
$cb_args = array_merge( array($output, $element, $depth - 1), $args);
$output = call_user_func_array(array(&$this, 'istart_el'), $cb_args);
}
}
$previous_element = $element;
}
return $output;
}
}
class iWalker_Page extends iWalker {
var $tree_type = 'page';
var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID'); //TODO: decouple this
function istart_lvl($output, $depth) {
$indent = str_repeat("\t", $depth);
$output .= "\n$indent\n";
return $output;
}
function iend_lvl($output, $depth) {
$indent = str_repeat("\t", $depth);
$output .= "$indent
\n";
return $output;
}
function istart_el($output, $page, $depth, $current_page, $args) {
if ( $depth )
$indent = str_repeat("\t", $depth);
extract($args, EXTR_SKIP);
$css_class = 'page_item';
$_current_page = get_page( $current_page );
if ( $page->ID == $current_page )
$css_class .= ' current_page_item';
elseif ( $_current_page && $page->ID == $_current_page->post_parent )
$css_class .= ' current_page_parent';
$output .= $indent . '' . apply_filters('the_title', $page->post_title) . '';
if ( !empty($show_date) ) {
if ( 'modified' == $show_date )
$time = $page->post_modified;
else
$time = $page->post_date;
$output .= " " . mysql2date($date_format, $time);
}
return $output;
}
function iend_el($output, $page, $depth) {
$output .= "\n";
return $output;
}
function iparent_start($output, $page, $depth, $current_page, $args) {
if ( $depth )
$indent = str_repeat("\t", $depth);
extract($args, EXTR_SKIP);
$css_class = 'page_item';
$_current_page = get_page( $current_page );
if ( $page->ID == $current_page )
$css_class .= ' current_page_item';
elseif ( $_current_page && $page->ID == $_current_page->post_parent )
$css_class .= ' current_page_parent';
$output .= $indent . '' . apply_filters('the_title', $page->post_title) . '';
if ( !empty($show_date) ) {
if ( 'modified' == $show_date )
$time = $page->post_modified;
else
$time = $page->post_date;
$output .= " " . mysql2date($date_format, $time);
}
return $output;
}
function iparent_end($output, $page, $depth) {
$output .= "\n";
return $output;
}
}