如何手动调整WordPress文章中自定义作者分类的显示顺序?
你的核心问题是WordPress默认自定义分类不会保存用户选择的顺序,无论是后台显示还是前端获取都会自动按字母/ID排序。以下是具体解决思路和代码实现:
问题根源
默认情况下,WordPress的非层级自定义分类(你的authors分类未开启hierarchical)在后台添加时会自动按字母排序,且get_the_terms返回的分类项顺序由数据库存储规则决定,不会保留用户选择的先后顺序。
解决方案
通过自定义MetaBox实现可排序的作者选择,并将顺序保存到文章元数据中,前端读取该元数据按自定义顺序展示。
1. 修改自定义分类注册代码
替换默认的MetaBox为自定义实现,关闭REST API支持避免块编辑器自动排序:
function wporg_register_taxonomy_authors() { $labels = array( 'name' => _x('Authors', 'taxonomy general name'), 'singular_name' => _x('Author', 'taxonomy singular name'), 'search_items' => __('Search Authors'), 'all_items' => __('All Authors'), 'parent_item' => __('Parent Authors'), 'parent_item_colon' => __('Parent Author:'), 'edit_item' => __('Edit Author'), 'update_item' => __('Update Author'), 'add_new_item' => __('Add New Author'), 'new_item_name' => __('New Author Name'), 'menu_name' => __('Authors'), ); $args = array( 'labels' => $labels, 'show_ui' => true, 'public' => true, 'show_in_rest' => false, // 关闭REST支持,改用自定义MetaBox 'show_admin_column' => true, 'query_var' => true, 'rewrite' => ['slug' => 'author'], 'meta_box_cb' => 'wporg_authors_meta_box', // 指定自定义MetaBox回调 ); register_taxonomy('authors', ['post'], $args); } add_action('init', 'wporg_register_taxonomy_authors');
2. 实现可排序的自定义MetaBox
创建支持拖拽排序、添加/删除作者的MetaBox,并保存顺序到文章元数据:
// 注册自定义MetaBox function wporg_add_authors_meta_box() { add_meta_box( 'wporg-authors-meta-box', __('Authors'), 'wporg_authors_meta_box', 'post', 'side', 'default' ); } add_action('add_meta_boxes', 'wporg_add_authors_meta_box'); // MetaBox内容输出 function wporg_authors_meta_box($post) { wp_nonce_field('wporg_save_authors_order', 'wporg_authors_nonce'); $selected_authors = get_post_meta($post->ID, '_wporg_authors_order', true); $selected_authors = is_array($selected_authors) ? $selected_authors : []; $all_authors = get_terms(['taxonomy' => 'authors', 'hide_empty' => false]); ?> <div id="wporg-authors-sortable"> <?php foreach ($selected_authors as $term_id) : $term = get_term($term_id, 'authors'); if (!$term || is_wp_error($term)) continue; ?> <div class="wporg-author-item" data-term-id="<?php echo esc_attr($term_id); ?>"> <?php echo esc_html($term->name); ?> <button type="button" class="wporg-remove-author button button-small">×</button> </div> <?php endforeach; ?> </div> <div class="wporg-add-author"> <select id="wporg-author-select"> <option value=""><?php _e('Select an author'); ?></option> <?php foreach ($all_authors as $term) : if (in_array($term->term_id, $selected_authors)) continue; ?> <option value="<?php echo esc_attr($term->term_id); ?>"><?php echo esc_html($term->name); ?></option> <?php endforeach; ?> </select> <button type="button" id="wporg-add-author-btn" class="button button-small"><?php _e('Add'); ?></button> </div> <style> #wporg-authors-sortable {margin:0 0 10px;padding:5px;border:1px solid #ddd;border-radius:4px;min-height:40px;} .wporg-author-item {padding:5px 8px;margin:5px 0;background:#f5f5f5;border-radius:3px;cursor:move;display:flex;justify-content:space-between;align-items:center;} .wporg-remove-author {padding:0 6px;line-height:18px;height:18px;} </style> <script> jQuery(document).ready(function($) { $('#wporg-authors-sortable').sortable({ placeholder: 'wporg-author-placeholder', cursor: 'move', update: updateSelectedAuthors }); $('#wporg-add-author-btn').click(function() { const termId = $('#wporg-author-select').val(); if (!termId) return; const termName = $('#wporg-author-select option:selected').text(); const item = $(`<div class="wporg-author-item" data-term-id="${termId}">${termName}<button type="button" class="wporg-remove-author button button-small">×</button></div>`); $('#wporg-authors-sortable').append(item); $('#wporg-author-select option[value="' + termId + '"]').remove(); updateSelectedAuthors(); }); $(document).on('click', '.wporg-remove-author', function() { const item = $(this).parent(); const termId = item.data('term-id'); const termName = item.text().replace('×', '').trim(); $('#wporg-author-select').append(`<option value="${termId}">${termName}</option>`); $('#wporg-author-select option').sort((a,b) => $(a).text().localeCompare($(b).text())).appendTo('#wporg-author-select'); item.remove(); updateSelectedAuthors(); }); function updateSelectedAuthors() { const selectedIds = $('#wporg-authors-sortable .wporg-author-item').map((i, el) => $(el).data('term-id')).get(); const hiddenField = $('#wporg-selected-authors').length ? $('#wporg-selected-authors') : $('<input type="hidden" id="wporg-selected-authors" name="wporg_selected_authors">').appendTo('#wporg-authors-meta-box'); hiddenField.val(selectedIds.join(',')); } updateSelectedAuthors(); }); </script> <?php } // 保存作者顺序到文章元数据 function wporg_save_authors_order($post_id) { if (!isset($_POST['wporg_authors_nonce']) || !wp_verify_nonce($_POST['wporg_authors_nonce'], 'wporg_save_authors_order')) return; if (!current_user_can('edit_post', $post_id)) return; if (isset($_POST['wporg_selected_authors'])) { $selected_authors = array_filter(array_map('intval', explode(',', $_POST['wporg_selected_authors']))); update_post_meta($post_id, '_wporg_authors_order', $selected_authors); wp_set_object_terms($post_id, $selected_authors, 'authors', false); } else { delete_post_meta($post_id, '_wporg_authors_order'); wp_set_object_terms($post_id, [], 'authors', false); } } add_action('save_post', 'wporg_save_authors_order');
3. 前端按自定义顺序显示作者
修改前端代码,读取保存的元数据顺序并展示:
<?php $selected_authors = get_post_meta(get_the_ID(), '_wporg_authors_order', true); if (!empty($selected_authors) && is_array($selected_authors)) { $author_items = []; foreach ($selected_authors as $term_id) { $term = get_term($term_id, 'authors'); if ($term && !is_wp_error($term)) { $author_items[] = '<p class="author">' . esc_html($term->name) . '</p>'; } } echo implode('<span>,</span>', $author_items); } ?>
效果说明
- 后台编辑文章时,Authors MetaBox支持拖拽调整顺序,添加/删除作者
- 保存后,前端会严格按照后台设置的顺序显示作者
- 同时会同步更新文章的分类关联,保证分类查询功能正常
内容的提问来源于stack exchange,提问作者dani1026
相关产品推荐
相关产品推荐

