Wordpress Plugin Boilerplate - 如何正确使用 WP_List_Table 类?
Posted
技术标签:
【中文标题】Wordpress Plugin Boilerplate - 如何正确使用 WP_List_Table 类?【英文标题】:Wordpress Plugin Boilerplate - How to use WP_List_Table class correctly? 【发布时间】:2021-06-08 23:23:38 【问题描述】:我使用Wordpress Plugin Boilerplate 作为我自己插件的基础。在管理区域中,我打算使用 Wordpress 的 WP_List_Table 类来显示数据。我知道我必须创建自己的子类才能访问它。这样做不是问题,但是我收到以下错误:
致命错误:未捕获的错误:调用成员函数 render_screen_reader_content() on
在研究过程中,我发现了一些具有相同问题的案例(1、2),但没有一个解决方案适用于我的案例。
使用样板的结构,我在包含文件夹内的文件中创建了子类:
if ( !class_exists( 'WP_List_Table' ) )
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
if ( !class_exists( 'Hedwig_tables' ) )
class Hedwig_tables extends WP_List_Table
private array $hd_columns;
private array $hd_data;
private array $hd_hidden;
private array $hd_sortable;
private array $hd_column_names;
public function __construct()
//parent::__construct();
public function set_column_names(array $column_names)
$this->hd_column_names = $column_names;
public function set_columns(array $columns)
$this->hd_columns = $columns;
public function set_data(array $data)
$this->hd_data = $data;
public function set_hidden(array $hidden)
$this->hd_hidden = $hidden;
public function set_sortable(array $sortable)
$this->hd_sortable = $sortable;
public function prepare_items()
$this->_column_headers = array($this->hd_columns, $this->hd_hidden, $this->hd_sortable);
$this->items = $this->hd_data;
public function column_default( $item, $column_name ): mixed
if (in_array($column_name, $this->hd_column_names))
return $item[ $column_name ];
return print_r($item, true);
然后将该文件加载到样板文件的 load_dependencies()
函数中,该函数位于包含文件夹内的 class-plugin-name.php 中。
在样板文件的 class-plugin-name-admin.php(在 admin 文件夹内)中,我创建了一个生成管理菜单条目的函数。
public function add_hedwig_page()
$this->plugin_screen_hook_suffix = add_menu_page(
__( 'Hedwig Settings', 'Hedwig' ),
__( 'Hedwig Settings', 'Hedwig' ),
'manage_options',
$this->plugin_name,
array( $this, 'hedwig_admin_display_page' ),
'dashicons-buddicons-activity'
);
$this->plugin_screen_hook_suffix = add_submenu_page(
$this->plugin_name,
__( 'Hedwig Settings', 'Hedwig' ),
__( 'Hedwig Settings', 'Hedwig' ),
'manage_options',
$this->plugin_name,
array( $this, 'hedwig_admin_display_page' )
);
public function hedwig_admin_display_page()
include_once 'partials/hedwig-admin-display.php';
在 display.php 中调用了我在 class-plugin-name-admin.php 中创建的函数,该函数为 WP_List_Table 的子类创建对象。
public function get_data()
$hedwig_list_table = new Hedwig_tables();
$sql = "SELECT id, value FROM y";
$results = $this->wpdb->get_results($sql, ARRAY_A);
if (count($results)<=0)
?>
<div class="hedwig-msg-error"><?php _e('No data found.','Hedwig');?></div>
<?php
return false;
$hedwig_list_table->set_columns(
array(
'id' => __('ID','Hedwig'),
'value' => __('Art','Hedwig')
)
);
$hedwig_list_table->set_column_names(
array(
'id',
'value'
)
);
$hedwig_list_table->set_data($results);
$hedwig_list_table->set_hidden(array());
$hedwig_list_table->set_sortable(array());
$hedwig_list_table->prepare_items();
$hedwig_list_table->display();
return true;
根据我前面提到的研究,问题一定是在创建子类的对象时(see this answer)。我尝试在不同的地方使用add_actions()
(在管理类的__construct 上,在plugin-name.php 的run()
函数内尝试在生成菜单项后加载它或将类加载为$GLOBALS
. 我想出的一切都失败了。我曾经创建一些没有样板的较小插件,但在这个项目中,我实际上想切换到这个 OOP 并以这种方式启动新插件。
更新 #1
仍然没有解决方案,但我偶然发现了看起来很有希望的another solution。但是,在创建用于初始化子类的菜单项时使用函数也不起作用。
public function add_hedwig_page()
$this->plugin_screen_hook_suffix = add_menu_page(
__( 'Hedwig Settings', 'Hedwig' ),
__( 'Hedwig Settings', 'Hedwig' ),
'manage_options',
$this->plugin_name,
function()
$this->hedwig_list_table = new Hedwig_tables();
$this->hedwig_admin_display_page();
,
'dashicons-buddicons-activity'
);
$this->plugin_screen_hook_suffix = add_submenu_page(
$this->plugin_name,
__( 'Hedwig Settings', 'Hedwig' ),
__( 'Hedwig Settings', 'Hedwig' ),
'manage_options',
$this->plugin_name,
function()
$this->hedwig_list_table = new Hedwig_tables();
$this->hedwig_admin_display_page();
);
public function hedwig_admin_display_page()
include_once 'partials/hedwig-admin-display.php';
【问题讨论】:
【参考方案1】:您不应该像自定义类一样加载此类,因为这是核心类的扩展,并且它有更多依赖项可以依赖。不要使用add_action
或$GLOBALS
来初始化这个类。
如果你在includes
文件夹内class-plugin-name.php
的样板文件的load_dependencies()
函数中加载它,它将被过早实例化,并且无法正常运行。
相反,仅在需要时调用它,在您将用于输出该页面标记的 partials/hedwig-admin-display.php
中。
这样的东西应该在你的例子中起作用:
<?php $table = new Hedwig_tables(); ?>
<h1>Hedwig_tables</h1>
<div class="wrap">
<div id="poststuff">
<div id="post-body" class="metabox-holder">
<div id="post-body-content">
<div class="meta-box-sortables ui-sortable">
<?php $table->prepare_items();?>
<form method="get">
<?php $table->display(); ?>
</form>
</div>
</div>
</div>
<br class="clear">
</div>
</div>
【讨论】:
以上是关于Wordpress Plugin Boilerplate - 如何正确使用 WP_List_Table 类?的主要内容,如果未能解决你的问题,请参考以下文章
WordPress plugin 代码注入漏洞(CVE-2022-24663)
WordPress plugin 代码注入漏洞(CVE-2022-24663)
php 在wordpress函数中选中Use cache Plugin
markdown 链接,片段,提醒,收集点作为重新访问WordPress插件开发期间的笔记#WordPress #Plugin #PHP #Refere