WordPress如何实现在后台拖拉文章就可以重新排序(全网唯一教程)
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’ 就可以了。