大家好!今天咱们来聊聊 WordPress 后台列表的那些事儿!
先来个开场白:有没有觉得 WordPress 后台那些文章列表、用户列表看起来很统一、很舒服?想不想自己也做一个? 今天就带大家深入了解一下 WP_List_Table
这个神奇的类,看看怎么用它来轻松构建可扩展的后台列表页面。
一、 WP_List_Table
是个啥?
WP_List_Table
是 WordPress 内核提供的一个抽象类,专门用来生成后台列表页面的。它封装了分页、排序、批量操作等常见的功能,咱们只需要继承它,然后定义一些特定的方法,就能快速生成一个功能完善的列表页面,省时省力!
二、 准备工作:先建个插件目录!
俗话说,巧妇难为无米之炊,咱们先创建一个插件目录,把代码放进去:
- 在
wp-content/plugins/
目录下创建一个名为my-custom-list-table
的文件夹。 - 在这个文件夹里创建一个名为
my-custom-list-table.php
的文件。
然后在 my-custom-list-table.php
文件里写上插件的基本信息:
<?php
/*
Plugin Name: My Custom List Table
Description: A custom list table example.
Version: 1.0
Author: Your Name
*/
// 安全检查,防止直接访问
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
// 引入列表类 (稍后创建)
require_once plugin_dir_path( __FILE__ ) . 'class-my-list-table.php';
// 添加菜单项
add_action( 'admin_menu', 'my_custom_list_table_menu' );
function my_custom_list_table_menu() {
add_menu_page(
'My List Table', // 页面标题
'My List Table', // 菜单标题
'manage_options', // 权限
'my-list-table', // 菜单 slug
'my_custom_list_page' // 回调函数
);
}
// 列表页面回调函数
function my_custom_list_page() {
$my_list_table = new My_List_Table();
echo '<div class="wrap">';
echo '<h2>My Custom List Table</h2>';
$my_list_table->prepare_items(); // 准备数据
$my_list_table->display(); // 显示列表
echo '</div>';
}
三、 核心代码:继承 WP_List_Table
创建自己的列表类
接下来,才是重头戏!在 my-custom-list-table
目录下创建一个名为 class-my-list-table.php
的文件,然后开始撸代码!
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WP_List_Table' ) ) {
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}
class My_List_Table extends WP_List_Table {
/**
* 构造函数,初始化列表
*/
public function __construct() {
parent::__construct( [
'singular' => 'book', // 单数形式的名称,用于消息提示
'plural' => 'books', // 复数形式的名称,用于消息提示
'ajax' => false // 是否使用 AJAX 分页
] );
}
/**
* 定义列
*
* @return array 列的数组,键是列的 slug,值是列的标题
*/
public function get_columns() {
$columns = [
'cb' => '<input type="checkbox" />', // 复选框列
'title' => 'Title',
'author' => 'Author',
'isbn' => 'ISBN',
'actions' => 'Actions',
];
return $columns;
}
/**
* 定义可排序的列
*
* @return array 可排序列的数组,键是列的 slug,值是排序的参数 (orderby, asc/desc)
*/
public function get_sortable_columns() {
$sortable_columns = [
'title' => [ 'title', true ], // true means it's already sorted
'author' => [ 'author', false ], // false means not sorted
'isbn' => [ 'isbn', false ]
];
return $sortable_columns;
}
/**
* 定义批量操作
*
* @return array 批量操作的数组,键是操作的 slug,值是操作的标题
*/
public function get_bulk_actions() {
$actions = [
'delete' => 'Delete'
];
return $actions;
}
/**
* 处理复选框列
*
* @param object $item 当前行的数据
*
* @return string 复选框的 HTML
*/
public function column_cb( $item ) {
return sprintf(
'<input type="checkbox" name="book[]" value="%s" />', $item['ID']
);
}
/**
* 处理默认列的显示
*
* @param object $item 当前行的数据
* @param string $column_name 列的 slug
*
* @return mixed 列的内容
*/
public function column_default( $item, $column_name ) {
switch ( $column_name ) {
case 'author':
case 'isbn':
return $item[ $column_name ];
default:
return print_r( $item, true ); //Show the whole array for troubleshooting purposes
}
}
/**
* 处理 'title' 列的显示,添加编辑链接
*
* @param object $item 当前行的数据
*
* @return string 列的内容
*/
public function column_title( $item ) {
$edit_url = admin_url( 'admin.php?page=my-list-table&action=edit&id=' . $item['ID'] );
$delete_url = wp_nonce_url( admin_url( 'admin.php?page=my-list-table&action=delete&id=' . $item['ID'] ), 'delete_book_' . $item['ID'] );
$actions = [
'edit' => sprintf( '<a href="%s">Edit</a>', $edit_url ),
'delete' => sprintf( '<a href="%s">Delete</a>', $delete_url ),
];
return sprintf( '%1$s %2$s',
/*$1%s*/ $item['title'],
/*$2%s*/ $this->row_actions( $actions )
);
}
/**
* 处理 'actions' 列的显示,添加自定义操作链接
*
* @param object $item 当前行的数据
*
* @return string 列的内容
*/
public function column_actions( $item ) {
$view_url = '#'; // 替换成实际的查看链接
return sprintf( '<a href="%s">View</a>', $view_url );
}
/**
* 处理批量操作
*/
public function process_bulk_action() {
if ( 'delete' === $this->current_action() ) {
$ids = isset( $_REQUEST['book'] ) ? $_REQUEST['book'] : array();
if ( is_array( $ids ) ) {
foreach ( $ids as $id ) {
// 安全检查,验证 nonce
if ( ! isset( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'bulk_' . $this->_args['plural'] ) ) {
wp_die( 'Security check failed!' );
}
// 在这里执行删除操作,例如:
// delete_book( $id );
error_log("Deleting book ID: ".$id); // For debugging purposes. Replace with actual deletion code.
}
echo '<div class="updated"><p>Items deleted!</p></div>';
}
}
}
/**
* 准备列表项,包括数据、分页、排序等
*/
public function prepare_items() {
$columns = $this->get_columns();
$hidden = array();
$sortable = $this->get_sortable_columns();
$this->_column_headers = array( $columns, $hidden, $sortable );
$this->process_bulk_action();
$per_page = 5; // 每页显示的数量
$current_page = $this->get_pagenum(); // 当前页码
// 获取数据,这里用模拟数据
$data = $this->get_data();
// 排序
usort( $data, array( $this, 'usort_reorder' ) );
// 分页
$total_items = count( $data );
$data = array_slice( $data, ( ( $current_page - 1 ) * $per_page ), $per_page );
$this->items = $data;
$this->set_pagination_args( [
'total_items' => $total_items, // 总记录数
'per_page' => $per_page, // 每页显示的数量
'total_pages' => ceil( $total_items / $per_page ) // 总页数
] );
}
/**
* 获取模拟数据
*
* @return array 数据数组
*/
public function get_data() {
$data = [
[
'ID' => 1,
'title' => 'The Hitchhiker's Guide to the Galaxy',
'author' => 'Douglas Adams',
'isbn' => '978-0345391803'
],
[
'ID' => 2,
'title' => 'The Lord of the Rings',
'author' => 'J.R.R. Tolkien',
'isbn' => '978-0618260264'
],
[
'ID' => 3,
'title' => 'Pride and Prejudice',
'author' => 'Jane Austen',
'isbn' => '978-0141439518'
],
[
'ID' => 4,
'title' => 'Nineteen Eighty-Four',
'author' => 'George Orwell',
'isbn' => '978-0451524935'
],
[
'ID' => 5,
'title' => 'To Kill a Mockingbird',
'author' => 'Harper Lee',
'isbn' => '978-0446310789'
],
[
'ID' => 6,
'title' => 'The Great Gatsby',
'author' => 'F. Scott Fitzgerald',
'isbn' => '978-0743273565'
],
[
'ID' => 7,
'title' => 'Moby Dick',
'author' => 'Herman Melville',
'isbn' => '978-0142437243'
],
[
'ID' => 8,
'title' => 'War and Peace',
'author' => 'Leo Tolstoy',
'isbn' => '978-0140444179'
],
[
'ID' => 9,
'title' => 'One Hundred Years of Solitude',
'author' => 'Gabriel García Márquez',
'isbn' => '978-0061120036'
],
[
'ID' => 10,
'title' => 'Don Quixote',
'author' => 'Miguel de Cervantes',
'isbn' => '978-0060930814'
]
];
return $data;
}
/**
* 排序回调函数
*
* @param array $a 第一个元素
* @param array $b 第二个元素
*
* @return int 排序结果
*/
public function usort_reorder( $a, $b ) {
// If no sort, leave as is
$orderby = ( ! empty( $_GET['orderby'] ) ) ? $_GET['orderby'] : 'title';
// If no order, default to asc
$order = ( ! empty( $_GET['order'] ) ) ? $_GET['order'] : 'asc';
// Determine sort order
$result = strcmp( $a[ $orderby ], $b[ $orderby ] );
// Send final sort direction to usort
return ( ( $order === 'asc' ) ? $result : -$result );
}
}
四、 代码详解:逐行解读!
咱们来一行一行地看看代码,搞清楚每个部分的作用:
__construct()
: 构造函数,初始化列表。 重要的是定义singular
和plural
,用于显示消息, 以及ajax
是否使用 AJAX 分页。get_columns()
: 定义列表的列。 返回一个数组,键是列的 slug(唯一标识符),值是列的标题。cb
列是复选框列,用于批量操作。get_sortable_columns()
: 定义可排序的列。 返回一个数组,键是列的 slug,值是一个包含两个元素的数组,第一个元素是排序的参数(一般是列的 slug),第二个元素表示是否默认升序排列true
升序,false
降序。get_bulk_actions()
: 定义批量操作。 返回一个数组,键是操作的 slug,值是操作的标题。column_cb()
: 处理复选框列的显示。 返回复选框的 HTML 代码。$item
是当前行的数据。column_default()
: 处理默认列的显示。$item
是当前行的数据,$column_name
是列的 slug。 根据$column_name
返回对应列的内容。column_title()
: 处理 ‘title’ 列的显示,添加编辑链接。$item
是当前行的数据。 返回列的内容,包括标题和操作链接。这里用到了$this->row_actions()
方法,它会自动生成操作链接的 HTML 代码。process_bulk_action()
: 处理批量操作。 判断当前执行的操作,然后执行相应的操作。 这里只是简单地输出了删除的 ID,实际应用中需要执行数据库删除操作。prepare_items()
: 准备列表项,包括数据、分页、排序等。- 获取列、隐藏列、可排序列的信息。
- 处理批量操作。
- 设置分页参数,包括总记录数、每页显示的数量、总页数。
- 获取数据,并进行排序和分页。
- 将数据赋值给
$this->items
,以便列表显示。
get_data()
: 获取模拟数据。 实际应用中需要从数据库中获取数据。usort_reorder()
: 排序回调函数。 用于对数据进行排序。
五、 运行结果:见证奇迹的时刻!
- 激活
my-custom-list-table
插件。 - 登录 WordPress 后台,点击 "My List Table" 菜单,就能看到咱们自定义的列表页面啦!
六、 扩展功能:让列表更强大!
WP_List_Table
的强大之处在于它的可扩展性。咱们可以根据自己的需求,添加各种各样的功能:
- 自定义列: 添加更多的列,显示更多的数据。
- 自定义操作: 添加更多的操作链接,例如查看、下载等。
- 搜索功能: 添加搜索框,方便用户查找数据。
- 过滤功能: 添加过滤器,让用户可以根据条件过滤数据。
- AJAX 分页: 使用 AJAX 分页,提高用户体验。
- 自定义 CSS: 修改 CSS 样式,让列表看起来更美观。
七、 进阶技巧:更上一层楼!
- 使用 WordPress API: 尽量使用 WordPress 提供的 API 来操作数据,例如
WP_Query
、WPDB
等。 - 安全第一: 注意安全,防止 SQL 注入、XSS 攻击等。
- 代码规范: 遵循 WordPress 代码规范,让代码更易读、易维护。
- 性能优化: 对列表进行性能优化,提高加载速度。
八、 举一反三:更多应用场景!
WP_List_Table
不仅仅可以用来显示图书列表,还可以用来显示各种各样的数据:
- 用户列表
- 订单列表
- 评论列表
- 自定义文章类型列表
- 插件列表
- 主题列表
只要你想,就能用它来构建各种各样的后台列表页面!
九、 表格总结:核心方法一览
方法名 | 作用 |
---|---|
__construct() |
构造函数,初始化列表。定义单复数名称和是否使用AJAX。 |
get_columns() |
定义列表的列。返回一个数组,键是列的 slug,值是列的标题。 |
get_sortable_columns() |
定义可排序的列。返回一个数组,键是列的 slug,值是一个包含两个元素的数组,第一个元素是排序的参数,第二个元素表示是否默认升序排列。 |
get_bulk_actions() |
定义批量操作。返回一个数组,键是操作的 slug,值是操作的标题。 |
column_cb() |
处理复选框列的显示。返回复选框的 HTML 代码。 |
column_default() |
处理默认列的显示。根据 $column_name 返回对应列的内容。 |
column_{$column_name} |
处理特定列的显示。例如,column_title() 处理 ‘title’ 列的显示。 |
process_bulk_action() |
处理批量操作。判断当前执行的操作,然后执行相应的操作。 |
prepare_items() |
准备列表项,包括数据、分页、排序等。这是最重要的方法,负责获取数据、排序、分页,并将数据赋值给 $this->items 。 |
get_data() |
获取数据。实际应用中需要从数据库中获取数据。 |
usort_reorder() |
排序回调函数。用于对数据进行排序。 |
十、 最后的忠告:实践出真知!
光说不练假把式,光看不做等于零! 赶紧动手试试吧,只有在实践中才能真正理解 WP_List_Table
的强大之处!
今天的分享就到这里,希望对大家有所帮助! 祝大家编程愉快,早日成为 WordPress 大神! 咱们下次再见!