Die Listentabelle wird nicht gerendert, wenn $ this-> items gefüllt ist

Ich versuche, einer benutzerdefinierten Admin-Seite eine Listentabelle hinzuzufügen. Ich habe diesen Leitfaden und diese Referenzimplementierung befolgt .

Leider, wenn ich $this->items zum Hinzufügen der Daten definiere, wird nichts auf der Admin-Seite angezeigt (nicht einmal das HTML um die $this->items ) und es gibt keine Fehlermeldungen. Wenn ich diese Zeile kommentiere (Zeile 135 ), dann funktioniert es, abgesehen von dem offensichtlichen Mangel an Daten.

Mein Code:

  '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) || $pagedset_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(); ?> 

List Table Test

display() ?>

Der obige Code befindet sich in einer separaten Datei, die in functions.php mit require_once() .

Ich benutze WordPress 4.1.1

Was geht hier vor sich? Warum sollte alles verschwinden und kein Fehler gegeben werden?

Solutions Collecting From Web of "Die Listentabelle wird nicht gerendert, wenn $ this-> items gefüllt ist"

Ich habe den gleichen Fehler gemacht, als ich zum ersten Mal WP_List_Table implementiert WP_List_Table .

Das Problem ist, dass beim Aufruf von WP_List_Table::display() WordPress wiederum aufruft:

  • WP_List_Table :: display_rows_or_placeholder ()
  • WP_List_Table :: display_rows ()
  • WP_List_Tabelle :: single_row ()
  • WP_List_Tabelle :: single_row_columns ()

Die letzte function wird für jede Zeile aufgerufen. Wenn Sie sich seinen Code ansehen (siehe Quelle ), hat er:

 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 ); } 

Also ruft WordPress WP_List_Table::column_default() für jede Zeile auf, aber … diese Methode existiert nicht .

Zu deiner class hinzufügen:

 public function column_default($item, $column_name) { return $item[$column_name]; } 

Und Ihre Daten werden korrekt angezeigt.

Wenn Sie keine Daten hinzufügen, wird der Fehler nicht display_rows() , da WordPress nie mehr display_rows() und andere Methoden aufruft.


Bonus Notizen:

  1. In Ihrer prepare_items() -Methode verwenden Sie die Variable $perpage aber Sie definieren sie als $per_page (beachten Sie den Unterstrich), die eine Warnung durch Division durch Null verursacht (und die Paginierung funktioniert nicht)

  2. Der Code mysql_real_escape_string($_GET["orderby"]) ist nicht sicher, weil für 'orderby' SQL-Klausel mysql_real_escape_string() nicht genug ist. (Siehe den jüngsten Yoast SQL Injection Bug ).

    Mach etwas wie:

     $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; } 

    und tun Sie etwas Ähnliches wie für 'order' Klausel: sehr wahrscheinlich kann es nur entweder ASC oder DESC : erlauben Sie nichts anderes.

Jetzt zu Hause, habe ich Ihren Code tatsächlich ausgeführt. Ich habe das:

Schwerwiegender Fehler: Aufruf von undefinierter function convert_to_screen () in … / wp-admin / includes / class-wp-list-table.php in Zeile 88

Hinweis:

Bitte aktivieren Sie Debugging_in_WordPress bei der Entwicklung.

Jedenfalls führte mich das zu der folgenden Frage zu Stackoverflow :

  • WordPress WP List Table Implementierung

@ brasofilos Antwort hat sehr geholfen, nicht überraschend, denn er ist einer der führenden Köpfe in der WordPress-Entwicklung .

Nach seiner Antwort fehlt die Methode column_default , zusätzlich ist die _construct Methode anders. Aber Sie können das selbst lesen, hier ist ein paar Arbeiten – abgespeckte – Code:

 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 '
'; echo '

Test List Table

'; new Test_List_Table(); echo '
'; } 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; } }