diff --git a/wp-admin/admin-ajax.php b/wp-admin/admin-ajax.php index 07f4cde7d..9966d31e3 100644 --- a/wp-admin/admin-ajax.php +++ b/wp-admin/admin-ajax.php @@ -610,7 +610,19 @@ case 'add-tag' : // From Manage->Tags exit; } - echo _tag_row( $tag, '', $taxonomy ); + $level = 0; + $tag_full_name = false; + if ( is_taxonomy_hierarchical($taxonomy) ) { + $tag_full_name = $tag->name; + $_tag = $tag; + while ( $_tag->parent ) { + $_tag = get_term( $_tag->parent, $taxonomy ); + $tag_full_name = $_tag->name . ' — ' . $tag_full_name; + $level++; + } + $tag_full_name = esc_attr($tag_full_name); + } + echo _tag_row( $tag, $level, $tag_full_name, $taxonomy ); exit; break; case 'get-tagcloud' : @@ -1210,7 +1222,7 @@ case 'inline-save-tax': if ( !$tag || is_wp_error( $tag ) ) die( __('Tag not updated.') ); - echo _tag_row($tag, '', $taxonomy); + echo _tag_row($tag, 0, '', $taxonomy); } else { die( __('Tag not updated.') ); } diff --git a/wp-admin/edit-link-categories.php b/wp-admin/edit-link-categories.php index 701b35489..ba87e05a9 100644 --- a/wp-admin/edit-link-categories.php +++ b/wp-admin/edit-link-categories.php @@ -226,5 +226,5 @@ if ( $page_links ) - + diff --git a/wp-admin/edit-tag-form.php b/wp-admin/edit-tag-form.php index 5492200d0..4d0b61572 100644 --- a/wp-admin/edit-tag-form.php +++ b/wp-admin/edit-tag-form.php @@ -39,13 +39,22 @@ do_action('edit_tag_form_pre', $tag); ?> -

+

+ + + + + + + 0, 'hide_if_empty' => false, 'name' => 'parent', 'orderby' => 'name', 'taxonomy' => $taxonomy, 'selected' => $tag->parent, 'exclude' => $tag->term_id, 'hierarchical' => true, 'show_option_none' => __('None'))); ?>
+ +
- + diff --git a/wp-admin/edit-tags.php b/wp-admin/edit-tags.php index 555a01e1f..57ee50b8e 100644 --- a/wp-admin/edit-tags.php +++ b/wp-admin/edit-tags.php @@ -44,9 +44,9 @@ case 'add-tag': $ret = wp_insert_term($_POST['tag-name'], $taxonomy, $_POST); if ( $ret && !is_wp_error( $ret ) ) { - wp_redirect('edit-tags.php?message=1#addtag'); + wp_redirect("edit-tags.php?taxonomy=$taxonomy&message=1#addtag"); } else { - wp_redirect('edit-tags.php?message=4#addtag'); + wp_redirect("edit-tags.php?taxonomy=$taxonomy&message=4#addtag"); } exit; break; @@ -65,7 +65,7 @@ case 'delete': wp_delete_term( $tag_ID, $taxonomy); - $location = 'edit-tags.php'; + $location = 'edit-tags.php?taxonomy=' . $taxonomy; if ( $referer = wp_get_referer() ) { if ( false !== strpos($referer, 'edit-tags.php') ) $location = $referer; @@ -88,7 +88,7 @@ case 'bulk-delete': wp_delete_term( $tag_ID, $taxonomy); } - $location = 'edit-tags.php'; + $location = 'edit-tags.php?taxonomy=' . $taxonomy; if ( $referer = wp_get_referer() ) { if ( false !== strpos($referer, 'edit-tags.php') ) $location = $referer; @@ -120,7 +120,7 @@ case 'editedtag': $ret = wp_update_term($tag_ID, $taxonomy, $_POST); - $location = 'edit-tags.php'; + $location = 'edit-tags.php?taxonomy=' . $taxonomy; if ( $referer = wp_get_original_referer() ) { if ( false !== strpos($referer, 'edit-tags.php') ) $location = $referer; @@ -200,10 +200,13 @@ if ( empty($tags_per_page) || $tags_per_page < 1 ) $tags_per_page = apply_filters( 'edit_tags_per_page', $tags_per_page ); $tags_per_page = apply_filters( 'tagsperpage', $tags_per_page ); // Old filter -if ( !empty($_GET['s']) ) - $total_terms = count( get_terms( $taxonomy, array( 'search' => trim(stripslashes($_GET['s'])), 'number' => 0, 'hide_empty' => 0 ) ) ); -else +if ( !empty($_GET['s']) ) { + $searchterms = trim(stripslashes($_GET['s'])); + $total_terms = count( get_terms( $taxonomy, array( 'search' => $searchterms, 'number' => 0, 'hide_empty' => 0 ) ) ); +} else { + $searchterms = ''; $total_terms = wp_count_terms($taxonomy); +} $page_links = paginate_links( array( 'base' => add_query_arg( 'pagenum', '%#%' ), @@ -248,8 +251,6 @@ if ( $page_links ) @@ -312,6 +313,13 @@ else

+ +
+ + 0, 'hide_if_empty' => false, 'taxonomy' => $taxonomy, 'name' => 'parent', 'orderby' => 'name', 'hierarchical' => true, 'show_option_none' => __('None'))); ?> +

+
+
@@ -329,7 +337,7 @@ else
- + - - + - + @@ -254,14 +253,14 @@ function inline_edit_term_row($type) { foreach ( $columns as $column_name => $column_display_name ) { if ( isset( $core_columns[$column_name] ) ) continue; - do_action( 'quick_edit_custom_box', $column_name, $type ); + do_action( 'quick_edit_custom_box', $column_name, $type, $taxonomy ); } ?>

- + @@ -671,12 +670,18 @@ function wp_link_category_checklist( $link_id = 0 ) { * @param unknown_type $class * @return unknown */ -function _tag_row( $tag, $class = '', $taxonomy = 'post_tag' ) { +function _tag_row( $tag, $level, $class = '', $taxonomy = 'post_tag' ) { $count = number_format_i18n( $tag->count ); - $tagsel = ($taxonomy == 'post_tag' ? 'tag' : $taxonomy); + if ( 'post_tag' == $taxonomy ) + $tagsel = 'tag'; + elseif ( 'category' == $taxonomy ) + $tagsel = 'category_name'; + else + $tagsel = $taxonomy; $count = ( $count > 0 ) ? "$count" : $count; - $name = apply_filters( 'term_name', $tag->name ); + $pad = str_repeat( '— ', max(0, $level) ); + $name = apply_filters( 'term_name', $pad . ' ' . $tag->name ); $qe_data = get_term($tag->term_id, $taxonomy, object, 'edit'); $edit_link = "edit-tags.php?action=edit&taxonomy=$taxonomy&tag_ID=$tag->term_id"; $out = ''; @@ -694,15 +699,22 @@ function _tag_row( $tag, $class = '', $taxonomy = 'post_tag' ) { switch ($column_name) { case 'cb': - $out .= ' '; + if ( $tag->term_id != get_option('default_' . $taxonomy) ) + $out .= ' '; + else + $out .= ' '; break; case 'name': $out .= '' . $name . '
'; $actions = array(); $actions['edit'] = '' . __('Edit') . ''; $actions['inline hide-if-no-js'] = '' . __('Quick Edit') . ''; - $actions['delete'] = "term_id) . "'>" . __('Delete') . ""; + if ( $tag->term_id != get_option('default_' . $taxonomy) ) + $actions['delete'] = "term_id) . "'>" . __('Delete') . ""; + $actions = apply_filters('tag_row_actions', $actions, $tag); + $actions = apply_filters("${taxonomy}_row_actions", $actions, $tag); + $action_count = count($actions); $i = 0; $out .= '

'; @@ -714,7 +726,8 @@ function _tag_row( $tag, $class = '', $taxonomy = 'post_tag' ) { $out .= '
'; $out .= ''; + $out .= '
' . apply_filters('editable_slug', $qe_data->slug) . '
'; + $out .= '
' . $qe_data->parent . '
'; break; case 'description': $out .= "$tag->description"; @@ -758,23 +771,85 @@ function tag_rows( $page = 1, $pagesize = 20, $searchterms = '', $taxonomy = 'po $args = array('offset' => $start, 'number' => $pagesize, 'hide_empty' => 0); - if ( !empty( $searchterms ) ) { + if ( !empty( $searchterms ) ) $args['search'] = $searchterms; - } - - $tags = get_terms( $taxonomy, $args ); // convert it to table rows $out = ''; $count = 0; - foreach( $tags as $tag ) - $out .= _tag_row( $tag, ++$count % 2 ? ' class="alternate"' : '', $taxonomy ); + if ( is_taxonomy_hierarchical($taxonomy) ) { + // We'll need the full set of terms then. + $args['number'] = $args['offset'] = 0; + + $terms = get_terms( $taxonomy, $args ); + if ( !empty( $searchterms ) ) // Ignore children on searches. + $children = array(); + else + $children = _get_term_hierarchy($taxonomy); + + // Some funky recursion to get the job done is contained within, Skip it for non-hierarchical taxonomies for performance sake + $out .= _term_rows($taxonomy, $terms, $children, $page, $pagesize, $count); + } else { + $terms = get_terms( $taxonomy, $args ); + foreach( $terms as $term ) + $out .= _tag_row( $term, 0, ++$count % 2 ? ' class="alternate"' : '', $taxonomy ); + } // filter and send to screen echo $out; return $count; } +function _term_rows( $taxonomy, $terms, &$children, $page = 1, $per_page = 20, &$count, $parent = 0, $level = 0 ) { + + $start = ($page - 1) * $per_page; + $end = $start + $per_page; + + $output = ''; + foreach ( $terms as $key => $term ) { + + if ( $count >= $end ) + break; + + if ( $term->parent != $parent && empty($_GET['s']) ) + continue; + + // If the page starts in a subtree, print the parents. + if ( $count == $start && $term->parent > 0 && empty($_GET['s']) ) { + $my_parents = $parent_ids = array(); + $p = $term->parent; + while ( $p ) { + $my_parent = get_term( $p, $taxonomy ); + $my_parents[] = $my_parent; + $p = $my_parent->parent; + if ( in_array($p, $parent_ids) ) // Prevent parent loops. + break; + $parent_ids[] = $p; + } + unset($parent_ids); + + $num_parents = count($my_parents); + $count -= $num_parents; // Do not include parents in the per-page count, This is due to paging issues with unknown numbers of rows. + while ( $my_parent = array_pop($my_parents) ) { + $output .= "\t" . _tag_row( $my_parent, $level - $num_parents, ++$count % 2 ? ' class="alternate"' : '', $taxonomy ); + $num_parents--; + } + } + + if ( $count >= $start ) + $output .= "\t" . _tag_row( $term, $level, ++$count % 2 ? ' class="alternate"' : '', $taxonomy ); + else + ++$count; + + unset($terms[$key]); + + if ( isset($children[$term->term_id]) ) + $output .= _term_rows( $taxonomy, $terms, $children, $page, $per_page, $count, $term->term_id, $level + 1 ); + } + + return $output; +} + // define the columns to display, the syntax is 'internal name' => 'display name' /** * {@internal Missing Short Description}} diff --git a/wp-admin/js/tags.dev.js b/wp-admin/js/tags.dev.js index 968738e8c..de22409f1 100644 --- a/wp-admin/js/tags.dev.js +++ b/wp-admin/js/tags.dev.js @@ -34,7 +34,11 @@ jQuery(document).ready(function($) { $('#ajax-response').append(r); } else { $('#ajax-response').empty(); - $('#the-list').prepend(r); + var parent = form.find('select#parent').val(); + if ( parent > 0 && $('#tag-' + parent ).length > 0 ) // If the parent exists on this page, insert it below. Else insert it at the top of the list. + $('#the-list #tag-' + parent).after(r); + else + $('#the-list').prepend(r); $('input[type="text"]:visible, textarea:visible', form).val(''); } }); @@ -42,4 +46,4 @@ jQuery(document).ready(function($) { return false; }); -}); +}); \ No newline at end of file diff --git a/wp-admin/js/tags.js b/wp-admin/js/tags.js index 7501fa0db..192851565 100644 --- a/wp-admin/js/tags.js +++ b/wp-admin/js/tags.js @@ -1 +1 @@ -jQuery(document).ready(function(a){a(".delete-tag").live("click",function(g){var b=a(this),f=b.parents("tr"),c=true,d;if("undefined"!=showNotice){c=showNotice.warn()}if(c){d=b.attr("href").replace(/[^?]*\?/,"").replace(/action=delete/,"action=delete-tag");a.post(ajaxurl,d,function(e){if("1"==e){a("#ajax-response").empty();f.fadeOut("normal",function(){f.remove()})}else{if("-1"==e){a("#ajax-response").empty().append('

'+tagsl10n.noPerm+"

");f.children().css("backgroundColor","")}else{a("#ajax-response").empty().append('

'+tagsl10n.broken+"

");f.children().css("backgroundColor","")}}});f.children().css("backgroundColor","#f33")}return false});a("#submit").click(function(){var b=a(this).parents("form");if(!validateForm(b)){return false}a.post(ajaxurl,a("#addtag").serialize(),function(c){if(c.indexOf('

'+tagsl10n.noPerm+"

");tr.children().css("backgroundColor","")}else{$("#ajax-response").empty().append('

'+tagsl10n.broken+"

");tr.children().css("backgroundColor","")}}});tr.children().css("backgroundColor","#f33")}return false});$("#submit").click(function(){var form=$(this).parents("form");if(!validateForm(form)){return false}$.post(ajaxurl,$("#addtag").serialize(),function(r){if(r.indexOf('
0&&$("#tag-"+parent).length>0){$("#the-list #tag-"+parent).after(r)}else{$("#the-list").prepend(r)}$('input[type="text"]:visible, textarea:visible',form).val("")}});return false})}); \ No newline at end of file diff --git a/wp-admin/menu.php b/wp-admin/menu.php index de10bf79e..766222528 100644 --- a/wp-admin/menu.php +++ b/wp-admin/menu.php @@ -50,11 +50,7 @@ $menu[5] = array( __('Posts'), 'edit_posts', 'edit.php', '', 'open-if-no-js menu if ( ! in_array('post', (array) $tax->object_type, true) ) continue; - if ( $tax->hierarchical ) - $submenu['edit.php'][$i] = array( esc_attr($tax->label), 'manage_categories', 'categories.php?taxonomy=' . $tax->name ); - else - $submenu['edit.php'][$i] = array( esc_attr($tax->label), 'manage_categories', 'edit-tags.php?taxonomy=' . $tax->name ); - ++$i; + $submenu['edit.php'][$i++] = array( esc_attr($tax->label), 'manage_categories', 'edit-tags.php?taxonomy=' . $tax->name ); } $menu[10] = array( __('Media'), 'upload_files', 'upload.php', '', 'menu-top', 'menu-media', 'div' ); @@ -90,11 +86,7 @@ foreach ( (array) get_post_types( array('_show' => true) ) as $ptype ) { if ( ! in_array($ptype, (array) $tax->object_type, true) ) continue; - if ( $tax->hierarchical ) - $submenu["edit.php?post_type=$ptype"][$i] = array( esc_attr($tax->label), 'manage_categories', "categories.php?taxonomy=$tax->name&post_type=$ptype" ); - else - $submenu["edit.php?post_type=$ptype"][$i] = array( esc_attr($tax->label), 'manage_categories', "edit-tags.php?taxonomy=$tax->name&post_type=$ptype" ); - ++$i; + $submenu["edit.php?post_type=$ptype"][$i++] = array( esc_attr($tax->label), 'manage_categories', "edit-tags.php?taxonomy=$tax->name&post_type=$ptype" ); } } unset($ptype, $ptype_obj); diff --git a/wp-includes/taxonomy.php b/wp-includes/taxonomy.php index 6da0bf80a..14a1bd66f 100644 --- a/wp-includes/taxonomy.php +++ b/wp-includes/taxonomy.php @@ -786,13 +786,13 @@ function &get_terms($taxonomies, $args = '') { // don't limit the query results when we have to descend the family tree if ( ! empty($number) && ! $hierarchical && empty( $child_of ) && '' === $parent ) { - if( $offset ) + if ( $offset ) $limit = 'LIMIT ' . $offset . ',' . $number; else $limit = 'LIMIT ' . $number; - - } else + } else { $limit = ''; + } if ( !empty($search) ) { $search = like_escape($search); @@ -2446,4 +2446,5 @@ function is_object_in_taxonomy($object_type, $taxonomy) { return false; } + ?>