填充$This->项时不呈现列表表格

时间:2015-03-29 作者:gandalf3

我正在尝试添加list table 到自定义管理页。我一直在跟踪this guidethis reference implementation.

不幸的是,当我定义$this->items 要添加数据,nothing 显示在管理页面(甚至列表表周围的html)中,并且没有错误消息。如果我将该行注释掉(第行135), 然后,除了明显缺乏数据外,它还能工作。

我的代码:

<?php

add_action(\'admin_menu\', \'add_example_menues\');

function add_example_menues() {
    add_menu_page(\'test\', \'test\', \'administrator\', \'test-top\', \'build_test_page\');
    add_submenu_page(\'test-top\', \'All tests\', \'All tests\', \'administrator\', \'test-top\');
}

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

class test_List_Table extends WP_List_Table {
    function __construct() {
        parent::__construct( array(
            \'singular\' => \'test\',
            \'plural\' => \'tests\',
            \'ajax\' => false
        ));
    }


    function extra_tablenav ($which) {
        if ($which == "top") {
            echo "Top";
        }
        if ($which == "bottom") {
            echo "Bottom";
        }
    }

    function get_columns() {
        $columns = array(
            \'id\'    => \'ID\',
            \'title\'     => \'Title\',
            \'user_id\'   => \'User ID\',
            \'description\'   => \'Description\'
        );
        return $columns;
    }

    function get_sortable_columns() {
        return $sortable = array(
            \'id\'        => array(\'id\',false),
            \'title\'         => array(\'title\',false),
            \'user_id\'       => array(\'user_id\',false)
        );
    }

    function prepare_items() {
        global $wpdb;

        //data normally gotten from non-wp database. Wordpress db user has access, as per this SE post:
        //http://wordpress.stackexchange.com/questions/1604/using-wpdb-to-connect-to-a-separate-database
        $query = "SELECT `id`, `title`, `user_id`, `description` FROM otherdb.example_table";

        //pagination stuff
        $orderby = !empty($_GET["orderby"]) ? mysql_real_escape_string($_GET["orderby"]) : \'ASC\';
        $order = !empty($_GET["order"]) ? mysql_real_escape_string($_GET["order"]) : \'\';
        if(!empty($orderby) & !empty($order)){ $query.=\' ORDER BY \'.$orderby.\' \'.$order; }
        $totalitems = $wpdb->query($query);
        echo "$totalitems";
        $per_page = 5;
        $paged = !empty($_GET["paged"]) ? mysql_real_escape_string($_GET["paged"]) : \'\';
        if(empty($paged) || !is_numeric($paged) || $paged<=0 ){ $paged=1; }
        $totalpages = ceil($totalitems/$perpage);
        if(!empty($paged) && !empty($perpage)){
            $offset=($paged-1)*$perpage;
            $query.=\' LIMIT \'.(int)$offset.\',\'.(int)$perpage;
        }
        $this->set_pagination_args( array(
            "total_items" => 4,
            "total_pages" => 1,
            "per_page" => 5,
        ) );


        $columns = $this->get_columns();
        $hidden = array();
        $sortable = $this->get_sortable_columns();

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

        //actual data gotten from database, but for SE use hardcoded array
        //$data = $wpdb->get_results($query, ARRAY_N);

        $example_data = array(
                array(
                        \'id\'        => 1,
                        \'title\'     => \'nonsense\',
                        \'user_id\'    => 1,
                        \'description\'  => \'asdf\'
                ),
                array(
                        \'id\'        => 2,
                        \'title\'     => \'notanumber\',
                        \'user_id\'    => 2,
                        \'description\'  => \'404\'
                ),
                array(
                        \'id\'        => 3,
                        \'title\'     => \'I Am A Title\',
                        \'user_id\'    => 3,
                        \'description\'  => \'desc\'
                ),
                array(
                        \'id\'        => 4,
                        \'title\'     => \'Example\',
                        \'user_id\'    => 4,
                        \'description\'  => \'useless\'
                ),
                array(
                        \'id\'        => 5,
                        \'title\'     => \'aeou\',
                        \'user_id\'    => 5,
                        \'description\'  => \'keyboard layouts\'
                ),
                array(
                        \'id\'        => 6,
                        \'title\'     => \'example data\',
                        \'user_id\'    => 6,
                        \'description\'  => \'data example\'
                ),
                array(
                        \'id\'        => 7,
                        \'title\'     => \'last one\',
                        \'user_id\'       => 7,
                        \'description\'  => \'done\'
                )
            );


        //This is the line:
        $this->items = $example_data;
        //When the above line is commented, it works as expected (except for the lack of data, of course)
    }
}


function build_test_page() {

    $testListTable = new test_List_Table();
    $testListTable->prepare_items();

?>
<div class="wrap">

    <div id="icon-users" class="icon32"><br/></div>
    <h2>List Table Test</h2>

    <?php $testListTable->display() ?>

</div>
<?php
}
?>
上述代码位于单独的文件中,包含在functions.php 使用require_once().

我正在使用wordpress 4.1.1

这是怎么回事?为什么所有的东西都消失了,没有错误?

2 个回复
最合适的回答,由SO网友:gmazzap 整理而成

我第一次实现时也犯了同样的错误WP_List_Table.

问题是当你打电话的时候WP_List_Table::display() WordPress依次调用:

  • WP_List_Table::display_rows_or_placeholder()
  • WP_List_Table::display_rows()
  • WP_List_Table::single_row()
  • WP_List_Table::single_row_columns()source), 它有:

    if ( \'cb\' == $column_name ) {
       // you don\'t have \'cb\' column, code remove because not relevant
    } elseif ( method_exists( $this, \'column_\' . $column_name ) ) {
       // you don\'t have method named \'column_{$column_name}\',
       // code remove because not relevant 
    } else {
       // not relevant line
       echo $this->column_default( $item, $column_name );
    }
    
    所以WordPress打电话WP_List_Table::column_default() 每行,但。。。这种方法doesn\'t exist.

    添加到您的类:

    public function column_default($item, $column_name) {
        return $item[$column_name];
    }
    
    您的数据将正确显示。

    当您不添加数据时,错误不会显示,因为没有数据WordPress从不调用display_rows() 以及之后的其他方法。

    奖金备注:您的prepare_items() 方法使用变量$perpage 但你把它定义为$per_page (请注意下划线),这会导致以零除警告(分页不起作用)

    代码mysql_real_escape_string($_GET["orderby"])not 安全,因为\'orderby\' SQL子句mysql_real_escape_string() 这还不够。(参见recent Yoast SQL injection bug).

    执行以下操作:

    $orderby = \'id\'; // default
    $by = strtolower(filter_input(INPUT_GET, \'orderby\', FILTER_SANITIZE_STRING));
    if (in_array($by, array(\'title\', \'description\', \'user_id\'), true) {
        $orderby = $by;
    }
    
    并为\'order\' 子句:很可能只能是ASCDESC: 不要允许其他任何事情。

SO网友:Nicolai Grossherr

现在在家里,我实际上运行了你的代码。我得到了这个:

致命错误:调用中未定义的函数convert\\u to\\u screen()/wp管理/包括/类别wp列表。php在线88

Note:

请打开Debugging_in_WordPress 开发时。

不管怎样,这让我想到了关于堆栈溢出的以下问题:

  • Wordpress WP List Table Implemantation
      @brasofilo的回答帮助很大,这并不奇怪,因为他也是WordPress开发方面的领军人物之一。

      不管怎样,按照他的回答,你错过了方法column_default, 此外_construct 方法不同。但你可以自己阅读,下面是一些可操作的精简代码:

      add_action( \'admin_menu\', \'add_test_list_table_menues\' );
      function add_test_list_table_menues() {
          add_menu_page(
              \'test\', 
              \'test\', 
              \'manage_options\', 
              \'test-top\', 
              \'test_list_table_output\'
          );
      }
      
      function test_list_table_output() { 
          echo \'<div class="wrap">\';
          echo \'<h2>Test List Table</h2>\';
          new Test_List_Table(); 
          echo \'</div>\';
      }
      
      if( ! class_exists( \'WP_List_Table\' ) ) {
          require_once( ABSPATH . \'wp-admin/includes/class-wp-list-table.php\' );
      }
      
      class Test_List_Table extends WP_List_Table {
          public function __construct() {
              parent::__construct( array(
                  \'singular\' => \'test\',
                  \'plural\' => \'tests\',
                  \'ajax\' => false
              ));
              $this->prepare_items();
              $this->display();
          }
      
          function get_columns() {
              $columns = array(
                  \'tid\'    => \'ID\',
                  \'title\'     => \'Title\',
                  \'user_id\'   => \'User ID\',
                  \'description\'   => \'Description\'
              );
              return $columns;
          }
      
          function column_default( $item, $column_name ) {
              switch( $column_name ) {
                  case \'tid\':
                  case \'title\':
                  case \'user_id\':
                  case \'description\':
                      return $item[ $column_name ];
                  default:
                      return print_r( $item, true ) ;
              }
          }
      
          function prepare_items() {
              $example_data = array(
                      array(
                              \'tid\'        => 1,
                              \'title\'     => \'nonsense\',
                              \'user_id\'    => 1,
                              \'description\'  => \'asdf\'
                      ),
                      array(
                              \'tid\'        => 2,
                              \'title\'     => \'notanumber\',
                              \'user_id\'    => 2,
                              \'description\'  => \'404\'
                      ),
                      array(
                              \'tid\'        => 3,
                              \'title\'     => \'I Am A Title\',
                              \'user_id\'    => 3,
                              \'description\'  => \'desc\'
                      ),
                      array(
                              \'tid\'        => 4,
                              \'title\'     => \'Example\',
                              \'user_id\'    => 4,
                              \'description\'  => \'useless\'
                      ),
                      array(
                              \'tid\'        => 5,
                              \'title\'     => \'aeou\',
                              \'user_id\'    => 5,
                              \'description\'  => \'keyboard layouts\'
                      ),
                      array(
                              \'tid\'        => 6,
                              \'title\'     => \'example data\',
                              \'user_id\'    => 6,
                              \'description\'  => \'data example\'
                      ),
                      array(
                              \'tid\'        => 7,
                              \'title\'     => \'last one\',
                              \'user_id\'       => 7,
                              \'description\'  => \'done\'
                      )
                  );
      
              $columns = $this->get_columns();
              $hidden = array();
              $sortable = $this->get_sortable_columns();
              $this->_column_headers = array($columns, $hidden, $sortable);
              $this->items = $example_data;
          }
      }
      

结束

相关推荐

在管理员帖子wp-list-table之前/之后添加内容

我知道有两个钩子可以在分类法wp列表前后添加内容。是否有操作可在编辑上的post type wp list表格后添加内容。php页面?$taxonomy列表:add_action( \'category\' . \'_pre_add_form\', \'copy_above_form\' ); function copy_above_form( $taxonomy ) { echo \'<p>Above the WP-List-Table</p>\';&#x