WordPress如何实现在后台拖拉文章就可以重新排序(全网唯一教程)

Published
2023-04-26
浏览次数 :  339

首先我们要实现后台文章能拖拉

wordpress自带的jquery自带的有jquery ui, 就可以省去我们很多麻烦。

我们以wordpress的2021主题为例。

我们首先在assets文件夹js文件夹下面创建admin.js文件,然后在functions.php里面,通过admin_enqueue_scripts钩子导入进来, 因为这里只需要在后端拖拽,所以要导入到后端的界面,注意,添加js支撑库的时候一定要添加jquery-ui-sortable的库

add_action('admin_enqueue_scripts','ml_add_admin_js');

function ml_add_admin_js() {
	wp_enqueue_script('ml-admin-js',get_template_directory_uri() . '/assets/js/admin.js',array('jquery','jquery-ui-sortable'),'1.0.0',true);
}

然后我们通过wp_localize_script函数传递php变量到js, 传递ajaxurl, nonce等。我们通过wp_create_nonce这个函数在php里面创建nonce, 这里的nonce十分的重要,是验证权限的密匙:

function ml_add_admin_js() {
	wp_enqueue_script('ml-admin-js',get_template_directory_uri() . '/assets/js/admin.js',array('jquery','jquery-ui-sortable'),'1.0.0',true);
	wp_localize_script('ml-admin-js','ha_object',array(
		'ajaxurl' => admin_url('admin-ajax.php'),
		'nonce'  => wp_create_nonce('custom_reorder_nonce')

	));
}

保存之后,你打开管理面板的源代码,按ctrl+f 搜索ha_object, 就会看到已经生成了ha_object的对象,也生成了nonce的密匙。

接下来,我们添加js代码来实现后台页面能拖拉。

我们在admin.js添加下面代码:

jQuery(document).ready(function($) {
    $('tbody').sortable({});
    $('tbody').disableSelection();
});

其他都比较好理解,要实现拖拉只要将对象进行sortable初始化就可以。因为wp自带了jqeury的ui库,所以这里初始化之后已经直接可以拖拉了。这里选择的是将tbody直接进行拖拉初始化。这就意味着你后台所有的tbody都可以进行拖拉了。

然后我们在js里面添加核心的函数update来实现拖拉ui更新的时候发送ajax到服务器后台,好让后台能响应并调整数据:

jQuery(document).ready(function($) {
    $('tbody').sortable({
        opacity: 0.6,
        revert: true,
        cursor: 'move',
        handle: '.column-title',
        update: function(event, ui) {
            var postType = $('input[name="post_type"]').val();
            var order = $('tbody').sortable('serialize');
            
            $.ajax({
                type: 'POST',
                url: ha_object.ajaxurl,
                data: {
                    action: 'save_custom_post_order',
                    postType: postType,
                    order: order,
                    custom_post_order_nonce: ha_object.nonce
                },
                success: function(res) {
                    console.log(res.responseText);
                }
            });
        }
    });
    $('tbody').disableSelection();
});

上面的js代码实现了当拖拉相关对象的时候会发送ajax的post请求到ajaxurl, 发送的数据是 action 和postType和order和custom_post_order_none, 这些都会在接收的php里面会产生一个$_post的请求。

我们在php实现更新数据库里面的最终排序:

function save_custom_post_order(){
  // Verify the nonce before updating the menu_order value
if ( !isset( $_POST['custom_post_order_nonce'] ) || !wp_verify_nonce( $_POST['custom_post_order_nonce'], 'custom_post_order_action' ) ) {
    die( 'Invalid nonce' );
}
    global $wpdb;
    $post_type = $_POST['postType'];
    $order = $_POST['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++;
    }
    

    die('1');
}
add_action('wp_ajax_save_custom_post_order', 'save_custom_post_order');

首先我们在php文件里面验证nonce:

if ( !isset( $_POST['custom_post_order_nonce'] ) || !wp_verify_nonce( $_POST['custom_post_order_nonce'], 'custom_post_order_action' ) ) {
    die( 'Invalid nonce' );
}

然后我们来接收ajax请求的post,并通过parse_str函数把$order转化为数组$item:

global $wpdb;
    $post_type = $_POST['postType'];
    $order = $_POST['order'];

    parse_str($order, $items);

然后我们循环这个包含了所有id的数组(id是从js里面的sortable函数里面传递过来的), 并执行每一个循环的通过$wpdb更新数据库里面的menu_order的功能:

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


然后你通过pre_get_posts钩子调整文章排序:

function custom_post_order($query){
    if(is_admin() && $query->is_main_query()){
      if (is_category(  )) {
        $orderby = $query->get('orderby');
        
        if ($orderby != 'menu_order') {
            $query->set('orderby', 'menu_order');
            $query->set('order', 'ASC');
        }
        
      }
        
    }
}
add_action('pre_get_posts', 'custom_post_order');

这样实现了只有在管理页面的分类页面当中, 排序可以拖拉更新。

在前端页面循环的时候也要设置下wp_query的orderby =》 ‘menu_order’ 就可以了。


标签:
Top