我在试着定制WP_List_Table
扩展以显示自定义帖子类型。
下面是表和DOM的外观。您可以看到,它正在将表行呈现为空,并且没有标题。应该有两个职位,这样才能发挥更多的作用。
以下是页面代码:
<?php
function customer_list_page() {
if (!class_exists(\'WP_List_Table\')) {
require_once(ABSPATH . \'wp-admin/includes/class-wp-list-table.php\');
}
class CustomerList extends WP_List_Table {
public function __construct() {
parent::__construct([
\'singular\' => __(\'Customer\', \'text-domain\'),
\'plural\' => __(\'Customers\', \'text-domain\'),
\'ajax\' => false
]);
}
public static function get_customers() {
$query = new WP_Query(array(
\'post_type\' => \'customer\'
));
$customer_posts = $query->posts;
$customers = array();
foreach($customer_posts as $customer_post) {
$new_customer = array();
$new_customer[\'postId\'] = $customer_post->ID;
$new_customer[\'firstName\'] = get_post_meta($customer_post->ID, \'lws-first-name\', true);
$new_customer[\'lastName\'] = get_post_meta($customer_post->ID, \'lws-last-name\', true);
$new_customer[\'notes\'] = get_post_meta($customer_post->ID, \'lws-notes\', true);
$new_customer[\'customerId\'] = get_post_meta($customer_post->ID, \'lws-customer-id\', true);
$new_customer[\'email\'] = get_post_meta($customer_post->ID, \'lws-email\', true);
$new_customer[\'phone\'] = get_post_meta($customer_post->ID, \'lws-phone\', true);
$new_customer[\'mobile\'] = get_post_meta($customer_post->ID, \'lws-mobile\', true);
$new_customer[\'emailNotifications\'] = get_post_meta($customer_post->ID, \'lws-email-notifications\', true);
$new_customer[\'acceptChecks\'] = get_post_meta($customer_post->ID, \'lws-accept-checks\', true);
$new_customer[\'altContact\'] = get_post_meta($customer_post->ID, \'lws-alt-contact\', true);
$new_customer[\'altPhone\'] = get_post_meta($customer_post->ID, \'lws-alt-phone\', true);
$new_customer[\'street\'] = get_post_meta($customer_post->ID, \'lws-street\', true);
$new_customer[\'city\'] = get_post_meta($customer_post->ID, \'lws-city\', true);
$new_customer[\'state\'] = get_post_meta($customer_post->ID, \'lws-state\', true);
$new_customer[\'zip\'] = get_post_meta($customer_post->ID, \'lws-zip\', true);
$new_customer[\'pets\'] = json_decode(get_post_meta($customer_post->ID, \'lws-pets\', true));
array_push($customers, $new_customer);
}
return $customers;
}
public static function delete_customer($id) {
wp_delete_post($id);
}
public static function record_count() {
return wp_count_posts(\'customer\')->draft;
}
public function no_items() {
_e(\'No customers to display\', \'text-domain\');
}
function column_name($customer) {
$delete_nonce = wp_create_nonce(\'lws-delete-customer\');
$title = \'<strong>\' . $customer[\'firstName\'] . \' \' . $customer[\'lastName\'] . \'</strong>\';
$actions = [
\'delete\' => sprintf(\'<a href="?page=%s&action=%s&customer=%s&_wpnonce=%s">Delete</a>\', esc_attr($_REQUEST[\'page\']), \'delete\', absint($customer[\'postId\']), $delete_nonce)
];
return $title . $this->row_actions($actions);
}
function column_default($customer, $column_name) {
return $customer[$column_name];
}
function column_cb($customer) {
return sprintf(
\'<input type="checkbox" name="bulk-delete[]" value="%s"/>\', $customer[\'postId\']
);
}
function get_columns() {
return [
\'cb\' => \'<input type="checkbox" />\',
\'customerId\' => __(\'Customer ID\', \'text-domain\'),
\'name\' => __(\'Name\', \'text-domain\'),
\'email\' => __(\'E-Mail\', \'text-doamin\'),
\'phone\' => __(\'Phone #\', \'text-domain\')
];
}
public function get_sortable_columns() {
return [
\'customerId\' => [\'customerId\', true],
\'name\' => [\'name\', false],
\'email\' => [\'emial\', false],
\'phone\' => [\'phone\', false]
];
}
public function get_bulk_actions() {
return [
\'bulk-delete\' => \'Delete\'
];
}
public function prepare_items() {
$this->_column_headers = $this->get_column_info();
$this->process_bulk_actions();
$per_page = $this->get_items_per_page(\'customers_per_page\', 20);
$current_page = $this->get_pagenum();
$total_items = self::record_count();
$this->set_pagination_args([
\'total_items\' => $total_items,
\'per_page\' => $per_page
]);
$this->items = self::get_customers($per_page, $current_page);
}
public function process_bulk_action() {
if($this->current_action() === \'delete\') {
$nonce = esc_attr($_REQUEST[\'_wpnonce\']);
if(!wp_verify_nonce($nonce, \'lws-delete-customer\')) {
die(\'What the heck\');
}
else {
self::delete_customer(absint($_GET[\'customer\']));
wp_redirect(esc_url(add_query_arg()));
exit;
}
}
if(
(isset($_POST[\'action\']) && $_POST[\'action\'] == \'bulk-delete\') ||
(isset($_POST[\'action2\']) && $_POST[\'action2\'] == \'bulk-delete\')
) {
$delete_ids = esc_sql($_POST[\'bulk-delete\']);
foreach($delete_ids as $id) {
self::delete_customer($id);
}
wp_redirect(esc_url(add_query_arg()));
exit;
}
}
}
$customers_table = new CustomerList();
?>
<div class="wrap">
<h2>Customers</h2>
<form method="post">
<?php
$customers_table->prepare_items();
$customers_table->display();
?>
</form>
</div>
<?php
}
?>
我无法从调试中找出答案。据我所知,一切都与我所遵循的几乎一模一样
here.
最合适的回答,由SO网友:Sally CJ 整理而成
因为列标题是registered late. 您应该在页面上呈现管理通知之前,即WordPress触发钩子之前,注册标题(即初始化列表表类实例)admin_notices
.
但是你的customer_list_page()
函数,我相信它是add_menu_page()
或add_submenu_page()
, 只有在显示管理通知(和其他内容)后才会调用,因此get_column_headers()
(由使用WP_List_Table::get_column_info()
) 无法识别列表的列标题。那是因为get_column_headers()
将列标题存储在静态变量/数组中,一旦设置,将不再修改,因此下次为屏幕/页面调用该函数时,该函数将返回“旧”列标题。
更具体地说,您的类实例($customers_table = new CustomerList()
) 应在之前初始化WP_Screen::render_screen_meta()
已调用wp-admin/admin-header.php
. 如果你看WP_List_Table::single_row_columns()
由以下人员使用(尽管不是直接使用)WP_List_Table::display()
, 只有在列表表中注册了有效的列标题时,才会显示正文/内容行。因此,这就解释了为什么列标题对于要显示的内容行是必需的。就像人类没有脑袋就活不下去一样。。。(:D)
如果在呈现管理通知之前无法初始化类实例。。。您可以手动设置$_column_headers
值
中的So
prepare_items()
方法,只需替换此:
$this->_column_headers = $this->get_column_info();
使用此选项:
$this->_column_headers = [
$this->get_columns(),
[], // hidden columns
$this->get_sortable_columns(),
$this->get_primary_column_name(),
];
但尝试始终“按时”初始化它:)
下面是一个使用
load-<page hook>
hook:
class My_Plugin {
private $list_table;
public function __construct() {
add_action( \'admin_menu\', [ $this, \'add_admin_menus\' ] );
}
public function add_admin_menus() {
$hook_name = add_menu_page( \'Customers\', \'Customers\',
\'edit_posts\', \'my-page\', [ $this, \'render_admin_page\' ] );
// Initialize the list table instance when the page is loaded.
add_action( "load-$hook_name", [ $this, \'init_list_table\' ] );
}
public function init_list_table() {
$this->list_table = new CustomerList;
}
public function render_admin_page() {
?>
<div class="wrap my-plugin">
<h1>Customers</h1>
<?php $this->list_table->prepare_items(); ?>
<?php $this->list_table->display(); ?>
</div>
<?php
}
}
if ( is_admin() ) {
new My_Plugin;
}
这只是一个温和的提醒,要仔细检查
emial
在您的
get_sortable_columns()
... =) 快乐的编码!