探讨 WP_List_Table 类如何生成后台列表与分页逻辑

WP_List_Table 类:后台列表与分页逻辑深度剖析

大家好,今天我们来深入探讨 WordPress 中 WP_List_Table 类,这个类是构建 WordPress 后台列表页面的核心工具,它负责生成列表的结构、处理分页逻辑,并提供各种增强列表功能的钩子。我们将从基础用法开始,逐步分析其内部机制,并通过实例代码展示如何利用它构建自定义列表。

1. WP_List_Table 类的基本概念

WP_List_Table 类是一个抽象类,位于 wp-admin/includes/class-wp-list-table.php 文件中。要使用它,我们需要创建一个子类,并实现一些关键的抽象方法。该类的主要职责包括:

  • 数据展示: 负责从数据库或其他数据源获取数据,并将其格式化为列表的形式。
  • 列定义: 定义列表中显示的列,包括列标题、数据提取方式和排序方式。
  • 分页处理: 生成分页导航,并处理用户点击分页链接时的请求。
  • 批量操作: 允许用户选择多个条目,并对它们执行批量操作,例如删除或更改状态。
  • 搜索过滤: 提供搜索框,允许用户根据关键词过滤列表。

2. 创建自定义 WP_List_Table 子类

首先,我们需要创建一个类来继承 WP_List_Table。假设我们要创建一个显示书籍信息的列表,我们可以这样开始:

if ( ! class_exists( 'WP_List_Table' ) ) {
    require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}

class Book_List_Table extends WP_List_Table {

    /**
     * 构造函数,设置列表的一些基本属性
     */
    public function __construct() {

        parent::__construct( array(
            'singular' => 'book',     // 单数形式的名称,用于 URL 参数等
            'plural'   => 'books',    // 复数形式的名称
            'ajax'     => false       // 是否启用 AJAX 分页,这里先设为 false
        ) );

    }

    // ... 更多方法将在后面实现 ...
}

这段代码首先检查 WP_List_Table 类是否已加载,如果没有,则引入它。然后,我们创建了一个名为 Book_List_Table 的类,并继承了 WP_List_Table。在构造函数中,我们调用了父类的构造函数,并传递了一个包含 singularpluralajax 属性的数组。singularplural 用于生成 URL 参数和显示信息,ajax 用于控制是否使用 AJAX 分页。

3. 定义列:get_columns()

接下来,我们需要定义列表中显示的列。我们需要重写 get_columns() 方法来实现:

    /**
     * 定义列
     *
     * @return array  列的数组,键是列的 ID(用于排序等),值是列的标题
     */
    public function get_columns() {
        $columns = array(
            'cb'        => '<input type="checkbox" />', // 用于批量操作的选择框
            'title'     => '书名',
            'author'    => '作者',
            'isbn'      => 'ISBN',
            'price'     => '价格'
        );
        return $columns;
    }

get_columns() 方法返回一个关联数组,键是列的 ID,值是列的标题。cb 列是特殊列,用于显示批量操作的选择框。

4. 准备数据:prepare_items()

prepare_items() 方法是 WP_List_Table 类中最重要的方法之一。它负责从数据库或其他数据源获取数据,并将其格式化为列表的形式。

    /**
     * 准备列表数据
     */
    public function prepare_items() {

        $columns = $this->get_columns();
        $hidden = array(); // 隐藏的列,默认为空
        $sortable = $this->get_sortable_columns(); // 可排序的列

        $this->_column_headers = array( $columns, $hidden, $sortable );

        // 获取数据
        $data = $this->get_book_data();

        // 处理排序
        usort( $data, array( $this, 'usort_reorder' ) );

        // 处理分页
        $per_page = $this->get_items_per_page( 'books_per_page', 10 ); // 每页显示 10 条数据
        $current_page = $this->get_pagenum();
        $total_items = count( $data );

        $data = array_slice( $data, ( ( $current_page - 1 ) * $per_page ), $per_page );

        $this->items = $data;

        // 设置分页参数
        $this->set_pagination_args( array(
            'total_items' => $total_items,                  // 总条目数
            'per_page'    => $per_page,                     // 每页显示条目数
            'total_pages' => ceil( $total_items / $per_page )   // 总页数
        ) );
    }

让我们逐步分析这段代码:

  1. 获取列信息: 首先,我们获取列的定义、隐藏列和可排序的列。
  2. 设置列头: 我们将这些信息存储在 $this->_column_headers 属性中,WP_List_Table 类会使用这些信息来生成列头。
  3. 获取数据: 我们调用 get_book_data() 方法来获取书籍数据。这个方法需要我们自己实现,它应该从数据库或其他数据源获取数据。
  4. 处理排序: 我们使用 usort() 函数对数据进行排序,排序的依据是用户点击的列头。usort_reorder() 方法将在后面实现。
  5. 处理分页:
    • 我们使用 get_items_per_page() 方法获取每页显示的条目数,默认值为 10。
    • 我们使用 get_pagenum() 方法获取当前页码。
    • 我们使用 array_slice() 函数截取当前页的数据。
    • 我们将截取后的数据存储在 $this->items 属性中,WP_List_Table 类会使用这些数据来生成列表内容。
  6. 设置分页参数: 我们使用 set_pagination_args() 方法设置分页参数,包括总条目数、每页显示的条目数和总页数。这些参数会被 WP_List_Table 类用来生成分页导航。

5. 实现 get_book_data():模拟数据源

get_book_data() 方法需要我们自己实现,它负责从数据库或其他数据源获取数据。为了演示,我们可以创建一个模拟的数据源:

    /**
     * 获取书籍数据(模拟)
     *
     * @return array  书籍数据的数组
     */
    private function get_book_data() {
        $data = array(
            array(
                'id'    => 1,
                'title' => '百年孤独',
                'author' => '加西亚·马尔克斯',
                'isbn'  => '978-7-5063-4168-3',
                'price' => 29.80
            ),
            array(
                'id'    => 2,
                'title' => '红楼梦',
                'author' => '曹雪芹',
                'isbn'  => '978-7-02-000467-7',
                'price' => 39.00
            ),
            array(
                'id'    => 3,
                'title' => '三国演义',
                'author' => '罗贯中',
                'isbn'  => '978-7-02-000468-4',
                'price' => 45.00
            ),
            array(
                'id'    => 4,
                'title' => '水浒传',
                'author' => '施耐庵',
                'isbn'  => '978-7-02-000469-1',
                'price' => 35.00
            ),
            array(
                'id'    => 5,
                'title' => '西游记',
                'author' => '吴承恩',
                'isbn'  => '978-7-02-000470-7',
                'price' => 42.00
            ),
            // ... 更多书籍数据 ...
        );

        // 增加更多模拟数据,超过 10 条,方便测试分页
        for ($i = 6; $i <= 25; $i++) {
            $data[] = array(
                'id'    => $i,
                'title' => '书籍 ' . $i,
                'author' => '作者 ' . $i,
                'isbn'  => 'ISBN ' . $i,
                'price' => rand(20, 50) + 0.99
            );
        }

        return $data;
    }

这个方法返回一个包含书籍数据的数组。每个书籍数据都是一个关联数组,包含 idtitleauthorisbnprice 属性。

6. 实现列的显示:column_default()column_{column_name}()

我们需要实现 column_default() 方法来处理默认列的显示,并实现 column_{column_name}() 方法来处理特定列的显示。

    /**
     * 处理默认列的显示
     *
     * @param array  $item         当前行的数据
     * @param string $column_name  列的 ID
     *
     * @return mixed  列的内容
     */
    public function column_default( $item, $column_name ) {
        switch ( $column_name ) {
            case 'isbn':
            case 'price':
                return $item[ $column_name ];
            default:
                return '<em>暂无内容</em>'; // 如果没有匹配的列,显示 "暂无内容"
        }
    }

    /**
     * 处理 "title" 列的显示
     *
     * @param array $item 当前行的数据
     *
     * @return string  列的内容
     */
    public function column_title( $item ) {
        return '<strong>' . $item['title'] . '</strong>';
    }

    /**
     * 处理 "author" 列的显示
     *
     * @param array $item 当前行的数据
     *
     * @return string  列的内容
     */
    public function column_author( $item ) {
        return '<em>' . $item['author'] . '</em>';
    }

column_default() 方法接收两个参数:当前行的数据和列的 ID。它根据列的 ID 返回列的内容。column_{column_name}() 方法是特定列的显示方法,其中 {column_name} 是列的 ID。例如,column_title() 方法用于显示 title 列的内容。

7. 实现批量操作的选择框:column_cb()

我们需要实现 column_cb() 方法来显示批量操作的选择框:

    /**
     * 处理 "cb" 列的显示 (批量操作选择框)
     *
     * @param array $item 当前行的数据
     *
     * @return string  选择框的 HTML 代码
     */
    public function column_cb( $item ) {
        return sprintf(
            '<input type="checkbox" name="book[]" value="%s" />', $item['id']
        );
    }

    /**
     * 定义批量操作
     *
     * @return array  批量操作的数组,键是操作的 ID,值是操作的标题
     */
    public function get_bulk_actions() {
        $actions = array(
            'delete' => '删除'
        );
        return $actions;
    }

column_cb() 方法返回一个 HTML 代码,用于显示选择框。选择框的 name 属性是 book[]value 属性是书籍的 ID。get_bulk_actions() 方法返回一个数组,定义了批量操作。键是操作的 ID,值是操作的标题。

8. 实现排序:get_sortable_columns()usort_reorder()

我们需要实现 get_sortable_columns() 方法来定义可排序的列,并实现 usort_reorder() 方法来处理排序:

    /**
     * 定义可排序的列
     *
     * @return array  可排序列的数组,键是列的 ID,值是一个包含 'orderby' 和 'order' 元素的数组
     */
    public function get_sortable_columns() {
        $sortable_columns = array(
            'title'  => array( 'title', true ),  // true 表示默认升序
            'author' => array( 'author', false ), // false 表示默认降序
            'price'  => array( 'price', false )
        );
        return $sortable_columns;
    }

    /**
     * 处理排序
     *
     * @param array $a 第一个元素
     * @param array $b 第二个元素
     *
     * @return int  排序结果
     */
    public function usort_reorder( $a, $b ) {
        // 如果没有设置排序参数,则不排序
        $orderby = ( ! empty( $_GET['orderby'] ) ) ? $_GET['orderby'] : 'title';
        $order   = ( ! empty( $_GET['order'] ) )   ? $_GET['order']   : 'asc';

        $result = strcmp( $a[ $orderby ], $b[ $orderby ] );

        return ( ( $order === 'asc' ) ? $result : -$result );
    }

get_sortable_columns() 方法返回一个数组,定义了可排序的列。键是列的 ID,值是一个包含 orderbyorder 元素的数组。orderby 元素是用于排序的字段,order 元素表示默认的排序方式(true 表示升序,false 表示降序)。

usort_reorder() 方法接收两个参数:要比较的两个元素。它首先获取排序的字段和排序方式,然后使用 strcmp() 函数比较两个元素的指定字段的值。最后,它根据排序方式返回排序结果。

9. 显示列表:display()

现在,我们已经实现了 WP_List_Table 子类的所有必要方法。我们可以使用 display() 方法来显示列表:

    /**
     * 显示列表
     */
    public function display() {
        // 添加一个搜索框
        echo '<form method="get">';
        echo '<input type="hidden" name="page" value="' . $_REQUEST['page'] . '" />'; // 非常重要,保持页面上下文
        $this->search_box( 'search', 'search_id' ); // 'search' 是搜索框的文本,'search_id' 是搜索框的 ID
        echo '</form>';

        parent::display();
    }

display() 方法中,我们首先添加了一个搜索框,然后调用了父类的 display() 方法来显示列表。

10. 注册列表页面

最后,我们需要创建一个页面来显示列表。我们可以使用 add_menu_page() 函数来注册一个菜单项,并在该菜单项对应的页面上显示列表:

add_action( 'admin_menu', 'register_book_list_page' );

function register_book_list_page() {
    add_menu_page(
        '书籍列表',       // 页面标题
        '书籍管理',       // 菜单标题
        'manage_options',   // 权限
        'book-list',       // 菜单 slug
        'book_list_page_callback' // 回调函数
    );
}

function book_list_page_callback() {
    $book_list_table = new Book_List_Table();
    $book_list_table->prepare_items();
    echo '<div class="wrap">';
    echo '<h2>书籍列表</h2>';
    $book_list_table->display();
    echo '</div>';
}

这段代码首先使用 add_action() 函数注册一个 admin_menu 钩子,并在该钩子上注册一个名为 register_book_list_page() 的函数。register_book_list_page() 函数使用 add_menu_page() 函数注册一个菜单项,该菜单项对应的页面会调用 book_list_page_callback() 函数。book_list_page_callback() 函数创建了一个 Book_List_Table 对象,调用其 prepare_items() 方法准备数据,然后调用其 display() 方法显示列表。

11. 处理批量操作:process_bulk_action()

我们需要添加一个方法来处理批量操作。


    /**
     * 处理批量操作
     */
    public function process_bulk_action() {

        // 如果用户没有选择任何条目,则直接返回
        if ( 'delete' === $this->current_action() ) {
            $ids = isset( $_REQUEST['book'] ) ? $_REQUEST['book'] : array();
            if ( empty( $ids ) ) {
                return;
            }

            // 确认是数组
            if ( ! is_array( $ids ) ) {
                $ids = array( $ids );
            }

            // 这里可以添加删除书籍的逻辑,例如:
            // foreach ( $ids as $id ) {
            //     delete_book( $id );
            // }

            // 添加一个通知,显示删除成功
            echo '<div class="updated"><p>成功删除 ' . count( $ids ) . ' 本书籍!</p></div>';
        }
    }

book_list_page_callback() 函数中,我们需要在调用 $book_list_table->display() 之前调用 $book_list_table->process_bulk_action()

function book_list_page_callback() {
    $book_list_table = new Book_List_Table();
    $book_list_table->process_bulk_action(); // 处理批量操作
    $book_list_table->prepare_items();
    echo '<div class="wrap">';
    echo '<h2>书籍列表</h2>';
    $book_list_table->display();
    echo '</div>';
}

12. 实现搜索:search_box()

我们已经在display()方法中添加了搜索框,现在我们需要修改prepare_items()方法来处理搜索:

    /**
     * 准备列表数据
     */
    public function prepare_items() {

        $columns = $this->get_columns();
        $hidden = array(); // 隐藏的列,默认为空
        $sortable = $this->get_sortable_columns(); // 可排序的列

        $this->_column_headers = array( $columns, $hidden, $sortable );

        // 获取数据
        $data = $this->get_book_data();

        // 处理搜索
        $search_term = isset( $_REQUEST['s'] ) ? sanitize_text_field( $_REQUEST['s'] ) : '';
        if ( ! empty( $search_term ) ) {
            $data = array_filter( $data, function ( $item ) use ( $search_term ) {
                // 在标题、作者和 ISBN 中搜索
                return (
                    stripos( $item['title'], $search_term ) !== false ||
                    stripos( $item['author'], $search_term ) !== false ||
                    stripos( $item['isbn'], $search_term ) !== false
                );
            } );
        }

        // 处理排序
        usort( $data, array( $this, 'usort_reorder' ) );

        // 处理分页
        $per_page = $this->get_items_per_page( 'books_per_page', 10 ); // 每页显示 10 条数据
        $current_page = $this->get_pagenum();
        $total_items = count( $data );

        $data = array_slice( $data, ( ( $current_page - 1 ) * $per_page ), $per_page );

        $this->items = $data;

        // 设置分页参数
        $this->set_pagination_args( array(
            'total_items' => $total_items,                  // 总条目数
            'per_page'    => $per_page,                     // 每页显示条目数
            'total_pages' => ceil( $total_items / $per_page )   // 总页数
        ) );
    }

我们添加了一段代码来处理搜索。首先,我们从 $_REQUEST 数组中获取搜索关键词,并使用 sanitize_text_field() 函数对其进行过滤。然后,我们使用 array_filter() 函数过滤数据,只保留包含搜索关键词的条目。

13. 总结

我们详细介绍了 WP_List_Table 类的使用方法,包括创建子类、定义列、准备数据、处理排序、处理分页、显示列表、处理批量操作和实现搜索。通过这些步骤,我们可以构建自定义的 WordPress 后台列表页面。

14. 进一步探索与优化

以上代码提供了一个 WP_List_Table 的基本实现。在实际应用中,可以进一步优化和扩展,例如:

  • AJAX 分页: 使用 AJAX 加载分页数据,提高用户体验。
  • 自定义列操作: 添加自定义列操作,例如编辑或删除按钮。
  • 更复杂的数据源: 从 WordPress 数据库或其他 API 获取数据。
  • 更强大的搜索过滤: 使用更高级的搜索算法和过滤器。
  • 使用 Transients 缓存数据: 缓存数据,减少数据库查询。

15. 代码示例

完整的 Book_List_Table 类代码如下:

if ( ! class_exists( 'WP_List_Table' ) ) {
    require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}

class Book_List_Table extends WP_List_Table {

    /**
     * 构造函数,设置列表的一些基本属性
     */
    public function __construct() {

        parent::__construct( array(
            'singular' => 'book',     // 单数形式的名称,用于 URL 参数等
            'plural'   => 'books',    // 复数形式的名称
            'ajax'     => false       // 是否启用 AJAX 分页,这里先设为 false
        ) );

    }

    /**
     * 定义列
     *
     * @return array  列的数组,键是列的 ID(用于排序等),值是列的标题
     */
    public function get_columns() {
        $columns = array(
            'cb'        => '<input type="checkbox" />', // 用于批量操作的选择框
            'title'     => '书名',
            'author'    => '作者',
            'isbn'      => 'ISBN',
            'price'     => '价格'
        );
        return $columns;
    }

    /**
     * 定义可排序的列
     *
     * @return array  可排序列的数组,键是列的 ID,值是一个包含 'orderby' 和 'order' 元素的数组
     */
    public function get_sortable_columns() {
        $sortable_columns = array(
            'title'  => array( 'title', true ),  // true 表示默认升序
            'author' => array( 'author', false ), // false 表示默认降序
            'price'  => array( 'price', false )
        );
        return $sortable_columns;
    }

    /**
     * 准备列表数据
     */
    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();

        // 获取数据
        $data = $this->get_book_data();

        // 处理搜索
        $search_term = isset( $_REQUEST['s'] ) ? sanitize_text_field( $_REQUEST['s'] ) : '';
        if ( ! empty( $search_term ) ) {
            $data = array_filter( $data, function ( $item ) use ( $search_term ) {
                // 在标题、作者和 ISBN 中搜索
                return (
                    stripos( $item['title'], $search_term ) !== false ||
                    stripos( $item['author'], $search_term ) !== false ||
                    stripos( $item['isbn'], $search_term ) !== false
                );
            } );
        }

        // 处理排序
        usort( $data, array( $this, 'usort_reorder' ) );

        // 处理分页
        $per_page = $this->get_items_per_page( 'books_per_page', 10 ); // 每页显示 10 条数据
        $current_page = $this->get_pagenum();
        $total_items = count( $data );

        $data = array_slice( $data, ( ( $current_page - 1 ) * $per_page ), $per_page );

        $this->items = $data;

        // 设置分页参数
        $this->set_pagination_args( array(
            'total_items' => $total_items,                  // 总条目数
            'per_page'    => $per_page,                     // 每页显示条目数
            'total_pages' => ceil( $total_items / $per_page )   // 总页数
        ) );
    }

    /**
     * 获取书籍数据(模拟)
     *
     * @return array  书籍数据的数组
     */
    private function get_book_data() {
        $data = array(
            array(
                'id'    => 1,
                'title' => '百年孤独',
                'author' => '加西亚·马尔克斯',
                'isbn'  => '978-7-5063-4168-3',
                'price' => 29.80
            ),
            array(
                'id'    => 2,
                'title' => '红楼梦',
                'author' => '曹雪芹',
                'isbn'  => '978-7-02-000467-7',
                'price' => 39.00
            ),
            array(
                'id'    => 3,
                'title' => '三国演义',
                'author' => '罗贯中',
                'isbn'  => '978-7-02-000468-4',
                'price' => 45.00
            ),
            array(
                'id'    => 4,
                'title' => '水浒传',
                'author' => '施耐庵',
                'isbn'  => '978-7-02-000469-1',
                'price' => 35.00
            ),
            array(
                'id'    => 5,
                'title' => '西游记',
                'author' => '吴承恩',
                'isbn'  => '978-7-02-000470-7',
                'price' => 42.00
            ),
            // ... 更多书籍数据 ...
        );

        // 增加更多模拟数据,超过 10 条,方便测试分页
        for ($i = 6; $i <= 25; $i++) {
            $data[] = array(
                'id'    => $i,
                'title' => '书籍 ' . $i,
                'author' => '作者 ' . $i,
                'isbn'  => 'ISBN ' . $i,
                'price' => rand(20, 50) + 0.99
            );
        }

        return $data;
    }

    /**
     * 处理默认列的显示
     *
     * @param array  $item         当前行的数据
     * @param string $column_name  列的 ID
     *
     * @return mixed  列的内容
     */
    public function column_default( $item, $column_name ) {
        switch ( $column_name ) {
            case 'isbn':
            case 'price':
                return $item[ $column_name ];
            default:
                return '<em>暂无内容</em>'; // 如果没有匹配的列,显示 "暂无内容"
        }
    }

    /**
     * 处理 "title" 列的显示
     *
     * @param array $item 当前行的数据
     *
     * @return string  列的内容
     */
    public function column_title( $item ) {
        return '<strong>' . $item['title'] . '</strong>';
    }

    /**
     * 处理 "author" 列的显示
     *
     * @param array $item 当前行的数据
     *
     * @return string  列的内容
     */
    public function column_author( $item ) {
        return '<em>' . $item['author'] . '</em>';
    }

    /**
     * 处理 "cb" 列的显示 (批量操作选择框)
     *
     * @param array $item 当前行的数据
     *
     * @return string  选择框的 HTML 代码
     */
    public function column_cb( $item ) {
        return sprintf(
            '<input type="checkbox" name="book[]" value="%s" />', $item['id']
        );
    }

    /**
     * 定义批量操作
     *
     * @return array  批量操作的数组,键是操作的 ID,值是操作的标题
     */
    public function get_bulk_actions() {
        $actions = array(
            'delete' => '删除'
        );
        return $actions;
    }

    /**
     * 处理批量操作
     */
    public function process_bulk_action() {

        // 如果用户没有选择任何条目,则直接返回
        if ( 'delete' === $this->current_action() ) {
            $ids = isset( $_REQUEST['book'] ) ? $_REQUEST['book'] : array();
            if ( empty( $ids ) ) {
                return;
            }

            // 确认是数组
            if ( ! is_array( $ids ) ) {
                $ids = array( $ids );
            }

            // 这里可以添加删除书籍的逻辑,例如:
            // foreach ( $ids as $id ) {
            //     delete_book( $id );
            // }

            // 添加一个通知,显示删除成功
            echo '<div class="updated"><p>成功删除 ' . count( $ids ) . ' 本书籍!</p></div>';
        }
    }

    /**
     * 处理排序
     *
     * @param array $a 第一个元素
     * @param array $b 第二个元素
     *
     * @return int  排序结果
     */
    public function usort_reorder( $a, $b ) {
        // 如果没有设置排序参数,则不排序
        $orderby = ( ! empty( $_GET['orderby'] ) ) ? $_GET['orderby'] : 'title';
        $order   = ( ! empty( $_GET['order'] ) )   ? $_GET['order']   : 'asc';

        $result = strcmp( $a[ $orderby ], $b[ $orderby ] );

        return ( ( $order === 'asc' ) ? $result : -$result );
    }

    /**
     * 显示列表
     */
    public function display() {
        // 添加一个搜索框
        echo '<form method="get">';
        echo '<input type="hidden" name="page" value="' . $_REQUEST['page'] . '" />'; // 非常重要,保持页面上下文
        $this->search_box( 'search', 'search_id' ); // 'search' 是搜索框的文本,'search_id' 是搜索框的 ID
        echo '</form>';

        parent::display();
    }
}

这段代码提供了一个完整的 Book_List_Table 类的实现,包括定义列、准备数据、处理排序、处理分页、显示列表、处理批量操作和实现搜索。

16. 将代码整合到 WordPress 中

将以上代码保存为一个 PHP 文件(例如 book-list-table.php),并将其放置在你的 WordPress 主题目录或插件目录中。然后,在你的主题的 functions.php 文件或插件的主文件中引入该文件:

require_once get_template_directory() . '/book-list-table.php'; // 如果在主题目录中
// 或者
require_once plugin_dir_path( __FILE__ ) . 'book-list-table.php'; // 如果在插件目录中

接下来,将注册列表页面的代码添加到你的主题的 functions.php 文件或插件的主文件中。

现在,你应该可以在 WordPress 后台看到一个名为 "书籍管理" 的菜单项,点击该菜单项即可看到书籍列表。

17. 掌握核心逻辑,灵活应对各种场景

WP_List_Table 类提供了强大的列表构建功能,掌握其核心逻辑,我们就能灵活应对各种 WordPress 后台列表的需求,构建功能丰富、用户友好的管理界面。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注