星期三 , 22 1 月 2025

怎样设置后台拖拉文章按照menu order重新排序

首先设置下js的支撑库 必须是jquery-ui-sortable 然后本地化添加必要入口

function wpd_add_admin_scripts() {
	wp_enqueue_media(  );
	wp_enqueue_script('theme_main_js', get_template_directory_uri() . '/js/main.js', array('jquery','jquery-ui-sortable'), '1.0.1', true);
	wp_localize_script( 'theme_main_js', 'wptutor',array(
		'ajax_url'  => admin_url('admin-ajax.php'),
		'rest_url'  => rest_url(),
		'nonce'  => wp_create_nonce( 'order_nonce' )
	) );
}

选择要拖拉的DOM并初始化

$(‘.edit-php tbody’).sortable()

然后添加必要的参数: 不理解逻辑的参数可以直接打印出来看

$('.edit-php tbody').sortable({
		opacity:0.6,
		revert:true,
		cursor:'move',
		handle:'.column-title',
		update:function(event,ui) {
			//发送wp ajax 更新下排序 
			let postType = $('input[name="post_type"]').val();
			let order = $('.edit-php tbody').sortable('serialize');

			//console.log(order); return;

			$.ajax({
				type:'POST',
				url:wptutor.ajax_url,
				data:{
					action:'wpt_custom_order',
					postType:postType,
					order:order,
					order_nonce:wptutor.nonce
				},
				
				success:(res) => {
					console.log(res);
				}

			});
			

		}

	});

创建后端的回调函数,最终实现的是要通过$wpdb更新数据表里的menu_order字段:

add_action( 'wp_ajax_wpt_custom_order', 'wpt_custom_order' );

function wpt_custom_order() {

	//检测下nonce 
	if (!isset($_POST['order_nonce']) || !wp_verify_nonce( $_POST['order_nonce'], 'order_nonce' )) {
		wp_send_json_error('Nonce is invalid');
	}

	global $wpdb;

	$post_type = $_POST['postType']; 

	$order = $_POST['order'];


	//打印$order 
	parse_str($order,$items); 
	$count = 1;


	foreach($items['post'] as $item_id) {
		$wpdb->update(
			$wpdb->posts,
			array(
				'menu_order' => $count
			),
			array('ID'  =>  $item_id)
		);
		$count++;
	}

	wp_send_json_success('successfully updated the order');
}

然后通过pre_get_posts调整在admin端或者你想要显示的前端部分的orderby , ZHUYI 这里一定要顺序是ASC ,

add_action( 'pre_get_posts', 'wpt_change_admin_order' );

function wpt_change_admin_order($query) {
	if (is_admin() && $query->is_main_query()) {
		// code...
		
			// code...
			$query->set('orderby','menu_order');

			$query->set('order','ASC');  //这里一定要设置ASC 因为拖拽排序之后当前页面的文章顺序的话就按照从1开始重新排序,虽然之前也又排序,但是更新成了重新排序,但是不在这页面的文章就不排序, 所以顺序就会变  所以要显示正确的排序的效果,就要设置ASC , 
	}

}

大家可以打印出menu_order在每篇文章上看看

add_filter( 'manage_posts_columns', 'wpt_add_order_to_menu' );
function wpt_add_order_to_menu($columns) {

	$columns['menu_order'] = __( 'menu_order' );
	return $columns;

}

add_action( 'manage_posts_custom_column','wpt_change_order_to_menu',10,2  );

function wpt_change_order_to_menu($column,$post_id) {
	switch ($column) {
		case 'menu_order':
			global $wpdb; 

			$menu_order = $wpdb->get_var("SELECT menu_order FROM $wpdb->posts WHERE ID = $post_id  ");

			echo $menu_order;
			break;
		
		
	}
}

要去理解parse_str的用法。 https://www.php.net/manual/en/function.parse-str.php

如果应用在所有文章上就会产生问题,如果单独用在分类上,也会产生问题,因为这个menu order如果一个变就会全部变,用在自定义文章类型上可以更好点,比方说产品这种,需要展示在前端八个之类的,通过这个就可以直接在前端调整顺序。

如何拖拉调整分类

最主要用到wp_update_term来更新字段

function enqueue_draggable_script() {
    wp_enqueue_script('jquery-ui-sortable');
}
add_action('admin_enqueue_scripts', 'enqueue_draggable_script');

function make_categories_draggable() {
    ?>
    <script type="text/javascript">
        jQuery(document).ready(function ($) {
            $(function () {
                $('#the-list').sortable({
                    axis: 'y',
                    update: function (event, ui) {
                        var data = {
                            action: 'update_category_order',
                            order: $('#the-list').sortable('serialize'),
                        };
                        $.post(ajaxurl, data);
                    },
                });
            });
        });
    </script>
    <?php
}
add_action('admin_footer', 'make_categories_draggable');

function update_category_order() {
    parse_str($_POST['order'], $categories_order);
    $counter = 0;

    foreach ($categories_order['category'] as $category_id) {
        wp_update_term((int)$category_id, 'category', array('menu_order' => $counter));
        $counter++;
    }

    die('1');
}
add_action('wp_ajax_update_category_order', 'update_category_order');

function update_category_order() {
    parse_str($_POST['order'], $categories_order);
    $counter = 0;

    foreach ($categories_order['taxonomy'] as $category_id) {
        update_term_meta((int)$category_id, 'custom_order', $counter);
        $counter++;
    }

    die('1');
}
add_action('wp_ajax_update_category_order', 'update_category_order');

//version three 
function update_category_order() {
    parse_str($_POST['order'], $category_order);

    foreach ($category_order['tag'] as $position => $category_id) {
        wp_update_term($category_id, 'category', array('term_order' => $position));
    }

    die();
}
add_action('wp_ajax_update_category_order', 'update_category_order');



//前后端查询排序
//前端
$categories = get_categories(array(
    'taxonomy' => 'category',
    'orderby' => 'meta_value_num',
    'meta_key' => 'custom_order',
    'order' => 'ASC',
));

//后端 用到pre_get_terms 
function custom_category_order_admin($query) {
    global $pagenow;

    // Check if we are on the category admin screen
    if (is_admin() && $pagenow == 'edit-tags.php' && isset($_GET['taxonomy']) && $_GET['taxonomy'] == 'category') {
        // Modify the query to order by custom_order meta
        $query->query_vars['orderby'] = 'meta_value_num';
        $query->query_vars['meta_key'] = 'custom_order';
        $query->query_vars['order'] = 'ASC';
    }
}
add_action('pre_get_terms', 'custom_category_order_admin');

//实际改变后端分类排序 
function modify_category_query($args, $taxonomies) {
    if (is_admin() && in_array('category', $taxonomies)) {
        $args['orderby'] = 'term_order';
        $args['order'] = 'DESC';
    }
    return $args;
}
add_filter('get_terms_args', 'modify_category_query', 10, 2);

add_action( 'get_terms_orderby', 'change_cat_orderby',10,3 );

function change_cat_orderby($orderby,$args,$taxonomies) {

	return $orderby;
}

function modify_category_query($args, $taxonomies) {
if (is_admin() && in_array(‘category’, $taxonomies)) {
$args[‘orderby’] = ‘term_order’;
$args[‘order’] = ‘ASC’;
}
return $args;
}
add_filter(‘get_terms_args’, ‘modify_category_query’, 10, 2);

add_filter( ‘get_terms_orderby’, ‘change_cat_orderby’,10,3 );

function change_cat_orderby($orderby,$args,$taxonomies) {

$orderby = ‘t.term_order DESC’;
return $orderby;

}

这个能用,能更改,只要设置is_admin

function custom_get_terms_orderby($args, $taxonomies) {
    // Check if this is the taxonomy you want to modify
    if (in_array('category', $taxonomies)) {
    	
        // Modify the orderby parameter
        $args['orderby'] = 'count'; // Replace 'name' with your desired orderby value
        $args['order'] = 'DESC';
    }

    return $args;
} 

add_filter('get_terms_args', 'custom_get_terms_orderby', 10, 2);

数据表有wp_term_relationships, 里面有term_order排序,但是要设置object_id

所以最终还是可以 更新数据库的形式来更新term_order

function update_category_term_order($term_id, $term_order) {
    global $wpdb;
    $wpdb->update($wpdb->terms, array('term_order' => $term_order), array('term_id' => $term_id));
}