首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义WP_List_Table显示空行

自定义WP_List_Table显示空行
EN

WordPress Development用户
提问于 2020-03-14 01:18:09
回答 1查看 2.1K关注 0票数 4

我正在尝试创建一个自定义WP_List_Table扩展来显示自定义post类型。

这是表和DOM的样子。您可以看到,它正在将表行呈现为空,而没有标头。应该有两个职位,这样才能发挥更多作用。

下面是页面的代码:

代码语言:javascript
复制
 __('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 = '' . $customer['firstName'] . ' ' . $customer['lastName'] . '';
      $actions = [
        'delete' => sprintf('Delete', 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(
        '', $customer['postId']
      );
    }

    function get_columns() {
      return [
        'cb' => '',
        '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();
  ?>
    
      Customers
      
        prepare_items();
          $customers_table->display();
        ?>

我无法从我的调试中找出它。据我所知,一切都与我遵循的这里几乎相同。

EN

回答 1

WordPress Development用户

回答已采纳

发布于 2020-03-14 14:54:33

获得空白行是因为您的列标题是registered晚于。您应该在页面上呈现管理通知之前,即在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() (虽然不是直接使用的),只有在为list表注册了有效的列标题时,主体/内容行才会显示。因此,这就解释了为什么要显示内容行必须使用列标题。好吧,就像人类没有脑袋就活不下去.(D)

如果无法在呈现管理员通知之前初始化类实例.您可以手动设置$_column_headers值.

因此,在prepare_items()方法中,只需替换以下内容:

代码语言:javascript
复制
$this->_column_headers = $this->get_column_info();

在这方面:

代码语言:javascript
复制
$this->_column_headers = [
    $this->get_columns(),
    [], // hidden columns
    $this->get_sortable_columns(),
    $this->get_primary_column_name(),
];

,但总是尝试初始化它“准时”。::)

下面是一个使用load-钩子的示例:

代码语言:javascript
复制
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() {
        ?>
            
                Customers
                list_table->prepare_items(); ?>
                list_table->display(); ?>

只是一个温和的提醒,以反复检查排字,如emial在您的get_sortable_columns(). =)快乐的编码!

票数 8
EN
页面原文内容由WordPress Development提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://wordpress.stackexchange.com/questions/360682

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档