diff --git a/wp-includes/classes.php b/wp-includes/classes.php
index c596e04d6b..dc61e799d6 100644
--- a/wp-includes/classes.php
+++ b/wp-includes/classes.php
@@ -400,4 +400,283 @@ function is_wp_error($thing) {
return false;
}
+
+// A class for displaying various tree-like structures. Extend the Walker class to use it, see examples at the bottom
+
+class Walker {
+ var $tree_type;
+ var $db_fields;
+
+ //abstract callbacks
+ function start_lvl($output) { return $output; }
+ function end_lvl($output) { return $output; }
+ function start_el($output) { return $output; }
+ function end_el($output) { return $output; }
+
+ function walk($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;
+
+ foreach ( $elements as $element ) {
+ // If flat, start and end the element and skip the level checks.
+ if ( $flat) {
+ // Start the element.
+ if ( $element->$id_field != 0 ) {
+ $cb_args = array_merge( array($output, $element, $depth - 1), $args);
+ $output = call_user_func_array(array(&$this, 'start_el'), $cb_args);
+ }
+
+ // End the element.
+ if ( $element->$id_field != 0 ) {
+ $cb_args = array_merge( array($output, $element, $depth - 1), $args);
+ $output = call_user_func_array(array(&$this, 'end_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);
+ $depth++; //always do this so when we start the element further down, we know where we are
+ if ( !$to_depth || ($depth < $to_depth) ) { //only descend if we're below $to_depth
+ $cb_args = array_merge( array($output, $depth - 1), $args);
+ $output = call_user_func_array(array(&$this, 'start_lvl'), $cb_args);
+ }
+ } 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, 'end_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, 'end_el'), $cb_args);
+ }
+
+ while ( $parent = array_shift($parents) ) {
+ $depth--;
+ if ( !$to_depth || ($depth < $to_depth) ) {
+ $cb_args = array_merge( array($output, $depth - 1), $args);
+ $output = call_user_func_array(array(&$this, 'end_lvl'), $cb_args);
+ $cb_args = array_merge( array($output, $parent, $depth - 1), $args);
+ $output = call_user_func_array(array(&$this, 'end_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, 'end_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, 'start_el'), $cb_args);
+ }
+ }
+
+ $previous_element = $element;
+ }
+
+ return $output;
+ }
+}
+
+class Walker_Page extends Walker {
+ var $tree_type = 'page';
+ var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID'); //TODO: decouple this
+
+ function start_lvl($output, $depth) {
+ $indent = str_repeat("\t", $depth);
+ $output .= "$indent
\n";
+ return $output;
+ }
+
+ function end_lvl($output, $depth) {
+ $indent = str_repeat("\t", $depth);
+ $output .= "$indent
\n";
+ return $output;
+ }
+
+ function start_el($output, $page, $depth, $current_page, $show_date, $date_format) {
+ if ( $depth )
+ $indent = str_repeat("\t", $depth);
+
+ $css_class = 'page_item';
+ if ( $page->ID == $current_page )
+ $css_class .= ' current_page_item';
+
+ $output .= $indent . '' . $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 end_el($output, $page, $depth) {
+ $output .= "\n";
+
+ return $output;
+ }
+
+}
+
+class Walker_PageDropdown extends Walker {
+ var $tree_type = 'page';
+ var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID'); //TODO: decouple this
+
+ function start_el($output, $page, $depth, $args) {
+ $pad = str_repeat(' ', $depth * 3);
+
+ $output .= "\t\n";
+
+ return $output;
+ }
+}
+
+class Walker_Category extends Walker {
+ var $tree_type = 'category';
+ var $db_fields = array ('parent' => 'category_parent', 'id' => 'cat_ID'); //TODO: decouple this
+
+ function start_lvl($output, $depth, $args) {
+ if ( 'list' != $args['style'] )
+ return $output;
+
+ $indent = str_repeat("\t", $depth);
+ $output .= "$indent\n";
+ return $output;
+ }
+
+ function end_lvl($output, $depth, $args) {
+ if ( 'list' != $args['style'] )
+ return $output;
+
+ $indent = str_repeat("\t", $depth);
+ $output .= "$indent
\n";
+ return $output;
+ }
+
+ function start_el($output, $category, $depth, $args) {
+ extract($args);
+
+ $link = 'category_description) )
+ $link .= 'title="'. sprintf(__("View all posts filed under %s"), wp_specialchars($category->cat_name)) . '"';
+ else
+ $link .= 'title="' . wp_specialchars(apply_filters('category_description',$category->category_description,$category)) . '"';
+ $link .= '>';
+ $link .= apply_filters('list_cats', $category->cat_name, $category).'';
+
+ if ( (! empty($feed_image)) || (! empty($feed)) ) {
+ $link .= ' ';
+
+ if ( empty($feed_image) )
+ $link .= '(';
+
+ $link .= '';
+ else
+ $link .= $name;
+ $link .= '';
+ if (empty($feed_image))
+ $link .= ')';
+ }
+
+ if ( $show_count )
+ $link .= ' ('.intval($category->category_count).')';
+
+ if ( $show_date ) {
+ $link .= ' ' . gmdate('Y-m-d', $category->last_update_timestamp);
+ }
+
+ if ( 'list' == $args['style'] ) {
+ $output .= "\tcat_ID == $current_category) && is_category() )
+ $output .= ' class="current-cat"';
+ $output .= ">$link\n";
+ } else {
+ $output .= "\t$link
\n";
+ }
+
+ return $output;
+ }
+
+ function end_el($output, $page, $depth) {
+ if ( 'list' != $args['style'] )
+ return $output;
+
+ $output .= "\n";
+ return $output;
+ }
+
+}
+
+class Walker_CategoryDropdown extends Walker {
+ var $tree_type = 'category';
+ var $db_fields = array ('parent' => 'category_parent', 'id' => 'cat_ID'); //TODO: decouple this
+
+ function start_el($output, $category, $depth, $args) {
+ $pad = str_repeat(' ', $depth * 3);
+
+ $cat_name = apply_filters('list_cats', $category->cat_name, $category);
+ $output .= "\t\n";
+
+ return $output;
+ }
+}
+
?>
diff --git a/wp-includes/functions.php b/wp-includes/functions.php
index 84586aa9e9..9a9cdd8b5c 100644
--- a/wp-includes/functions.php
+++ b/wp-includes/functions.php
@@ -714,128 +714,6 @@ function &get_page(&$page, $output = OBJECT) {
}
}
-function walk_tree($tree_type, $elements, $to_depth, $start_element_callback, $end_element_callback = '', $start_level_callback = '', $end_level_callback = '') {
- $args = array_slice(func_get_args(), 7);
- $parents = array();
- $depth = 1;
- $previous_element = '';
- $output = '';
-
- $last_element->post_parent = 0;
- $last_element->post_id = 0;
- $elements[] = $last_element;
-
- if ( 'page' == $tree_type ) {
- $parent_field = 'post_parent';
- $id_field = 'ID';
- } else {
- $parent_field = 'category_parent';
- $id_field = 'cat_ID';
- }
-
- $flat = false;
- if ( $to_depth == -1 )
- $flat = true;
-
- foreach ( $elements as $element ) {
- // If flat, start and end the element and skip the level checks.
- if ( $flat) {
- // Start the element.
- if ( !empty($start_element_callback) && ($element->$id_field != 0) ) {
- $cb_args = array_merge( array($output, $element, $depth), $args);
- $output = call_user_func_array($start_element_callback, $cb_args);
- }
-
- // End the element.
- if ( !empty($end_element_callback) && ($element->$id_field != 0) ) {
- $cb_args = array_merge( array($output, $element, $depth), $args);
- $output = call_user_func_array($end_element_callback, $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.
- $depth++; //always do this so when we start the element further down, we know where we are
- array_unshift($parents, $previous_element);
- if ( !$to_depth || ($depth < $to_depth) ) { //only descend if we're below $to_depth
- if ( !empty($start_level_callback) ) {
- $cb_args = array_merge( array($output, $depth), $args);
- $output = call_user_func_array($start_level_callback, $cb_args);
- }
- }
- } else if ( $element->$parent_field == $previous_element->$parent_field ) {
- // On the same level as previous element, so close the previous
- if ( !$to_depth || ($depth <= $to_depth) ) {
- if ( !empty($end_element_callback) ) {
- $cb_args = array_merge( array($output, $previous_element, $depth), $args);
- $output = call_user_func_array($end_element_callback, $cb_args);
- }
- }
- } else if ( $depth > 1 ) {
- // Ascend one or more levels.
- if ( !$to_depth || ($depth <= $to_depth) ) {
- if ( !empty($end_element_callback) ) {
- $cb_args = array_merge( array($output, $previous_element, $depth), $args);
- $output = call_user_func_array($end_element_callback, $cb_args);
- }
- }
-
- while ( $parent = array_shift($parents) ) {
- $depth--;
- if ( !$to_depth || ($depth < $to_depth) ) {
- if ( !empty($end_level_callback) ) {
- $cb_args = array_merge( array($output, $depth), $args);
- $output = call_user_func_array($end_level_callback, $cb_args);
- }
- if ( !empty($end_element_callback) ) {
- $cb_args = array_merge( array($output, $parent, $depth), $args);
- $output = call_user_func_array($end_element_callback, $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) ) {
- if ( !empty($end_element_callback) ) {
- $cb_args = array_merge( array($output, $previous_element, $depth), $args);
- $output = call_user_func_array($end_element_callback, $cb_args);
- }
- }
- }
-
- // Start the element.
- if ( !$to_depth || ($depth <= $to_depth) ) {
- if ( !empty($start_element_callback) && ($element->$id_field != 0) ) {
- $cb_args = array_merge( array($output, $element, $depth), $args);
- $output = call_user_func_array($start_element_callback, $cb_args);
- }
- }
-
- $previous_element = $element;
- }
-
- return $output;
-}
-
-function walk_page_tree($pages, $to_depth, $start_element_callback, $end_element_callback = '', $start_level_callback = '', $end_level_callback = '') {
- $args = array('page', $pages, $to_depth, $start_element_callback, $end_element_callback, $start_level_callback, $end_level_callback);
- $extra_args = array_slice(func_get_args(), 6);
-
- return call_user_func_array('walk_tree', array_merge($args, $extra_args));
-}
-
-function walk_category_tree($pages, $to_depth, $start_element_callback, $end_element_callback = '', $start_level_callback = '', $end_level_callback = '') {
- $args = array('category', $pages, $to_depth, $start_element_callback, $end_element_callback, $start_level_callback, $end_level_callback);
- $extra_args = array_slice(func_get_args(), 6);
- return call_user_func_array('walk_tree', array_merge($args, $extra_args));
-}
-
function get_category_by_path($category_path, $full_match = true, $output = OBJECT) {
global $wpdb;
$category_path = rawurlencode(urldecode($category_path));
diff --git a/wp-includes/template-functions-category.php b/wp-includes/template-functions-category.php
index d76cf0acc2..2886b9ad64 100644
--- a/wp-includes/template-functions-category.php
+++ b/wp-includes/template-functions-category.php
@@ -1,5 +1,17 @@
\n";
}
@@ -197,26 +209,6 @@ function wp_dropdown_categories($args = '') {
return $output;
}
-function _category_dropdown_element($output, $category, $depth, $selected, $args) {
- $pad = str_repeat(' ', $depth * 3);
-
- $cat_name = apply_filters('list_cats', $category->cat_name, $category);
- $output .= "\t\n";
-
- return $output;
-}
-
function wp_list_categories($args = '') {
if ( is_array($args) )
$r = &$args;
@@ -245,13 +237,13 @@ function wp_list_categories($args = '') {
$output .= __("No categories");
} else {
global $wp_query;
- $current_category = $wp_query->get_queried_object_id();
+ $r['current_category'] = $wp_query->get_queried_object_id();
if ( $hierarchical )
$depth = 0; // Walk the full depth.
else
$depth = -1; // Flat.
- $output .= walk_category_tree($categories, $depth, '_category_list_element_start', '_category_list_element_end', '_category_list_level_start', '_category_list_level_end', $current_category, $r);
+ $output .= walk_category_tree($categories, $depth, $r);
}
if ( $title_li && $list )
@@ -260,88 +252,6 @@ function wp_list_categories($args = '') {
echo apply_filters('list_cats', $output);
}
-function _category_list_level_start($output, $depth, $cat, $args) {
- if ( 'list' != $args['style'] )
- return $output;
-
- $indent = str_repeat("\t", $depth);
- $output .= "$indent\n";
- return $output;
-}
-
-function _category_list_level_end($output, $depth, $cat, $args) {
- if ( 'list' != $args['style'] )
- return $output;
-
- $indent = str_repeat("\t", $depth);
- $output .= "$indent
\n";
- return $output;
-}
-
-function _category_list_element_start($output, $category, $depth, $current_category, $args) {
- extract($args);
-
- $link = 'category_description) )
- $link .= 'title="'. sprintf(__("View all posts filed under %s"), wp_specialchars($category->cat_name)) . '"';
- else
- $link .= 'title="' . wp_specialchars(apply_filters('category_description',$category->category_description,$category)) . '"';
- $link .= '>';
- $link .= apply_filters('list_cats', $category->cat_name, $category).'';
-
- if ( (! empty($feed_image)) || (! empty($feed)) ) {
- $link .= ' ';
-
- if ( empty($feed_image) )
- $link .= '(';
-
- $link .= '';
- else
- $link .= $name;
- $link .= '';
- if (empty($feed_image))
- $link .= ')';
- }
-
- if ( $show_count )
- $link .= ' ('.intval($category->category_count).')';
-
- if ( $show_date ) {
- $link .= ' ' . gmdate('Y-m-d', $category->last_update_timestamp);
- }
-
- if ( 'list' == $args['style'] ) {
- $output .= "\tcat_ID == $current_category) && is_category() )
- $output .= ' class="current-cat"';
- $output .= ">$link\n";
- } else {
- $output .= "\t$link
\n";
- }
-
- return $output;
-}
-
-function _category_list_element_end($output, $category, $depth, $cat, $args) {
- if ( 'list' != $args['style'] )
- return $output;
-
- $output .= "\n";
- return $output;
-}
-
function in_category($category) { // Check if the current post is in the given category
global $category_cache, $post;
diff --git a/wp-includes/template-functions-post.php b/wp-includes/template-functions-post.php
index 26bfdce96a..62a6b312b2 100644
--- a/wp-includes/template-functions-post.php
+++ b/wp-includes/template-functions-post.php
@@ -278,6 +278,17 @@ function the_meta() {
Pages
*/
+function walk_page_tree() {
+ $walker = new Walker_Page;
+ $args = func_get_args();
+ return call_user_func_array(array(&$walker, 'walk'), $args);
+}
+
+function walk_page_dropdown_tree() {
+ $walker = new Walker_PageDropdown;
+ $args = func_get_args();
+ return call_user_func_array(array(&$walker, 'walk'), $args);
+}
function &get_page_children($page_id, $pages) {
global $page_cache;
@@ -381,7 +392,7 @@ function wp_dropdown_pages($args = '') {
if ( ! empty($pages) ) {
$output = "\n";
}
@@ -393,20 +404,6 @@ function wp_dropdown_pages($args = '') {
return $output;
}
-function _page_dropdown_element($output, $page, $depth, $selected) {
- $pad = str_repeat(' ', $depth * 3);
-
- $output .= "\t\n";
-
- return $output;
-}
-
function wp_list_pages($args = '') {
if ( is_array($args) )
$r = &$args;
@@ -428,7 +425,7 @@ function wp_list_pages($args = '') {
global $wp_query;
$current_page = $wp_query->get_queried_object_id();
- $output .= walk_page_tree($pages, $r['depth'], '_page_list_element_start', '_page_list_element_end', '_page_list_level_start', '_page_list_level_end', $current_page, $r['show_date'], $r['date_format']);
+ $output .= walk_page_tree($pages, $depth, $current_page, $r['show_date'], $r['date_format']);
if ( $r['title_li'] )
$output .= '';
@@ -442,46 +439,6 @@ function wp_list_pages($args = '') {
return $output;
}
-function _page_list_level_start($output, $depth) {
- $indent = str_repeat("\t", $depth);
- $output .= "$indent\n";
- return $output;
-}
-
-function _page_list_level_end($output, $depth) {
- $indent = str_repeat("\t", $depth);
- $output .= "$indent
\n";
- return $output;
-}
-
-function _page_list_element_start($output, $page, $depth, $current_page, $show_date, $date_format) {
- if ( $depth )
- $indent = str_repeat("\t", $depth);
-
- $css_class = 'page_item';
- if ( $page->ID == $current_page )
- $css_class .= ' current_page_item';
-
- $output .= $indent . '' . $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 _page_list_element_end($output, $page, $depth) {
- $output .= "\n";
-
- return $output;
-}
-
function the_attachment_link($id = 0, $fullsize = false, $max_dims = false) {
echo get_the_attachment_link($id, $fullsize, $max_dims);
}