Create Native Admin Tables In WordPress The Right Way

Advertisement

List tables are a common element in WordPress’ administration interface. They are used on nearly all default admin pages with lists, and developers often integrate them into their plugins. But creating one of these tables is not really intuitive if you haven’t done it before, and I’ve seen people try to replicate it by using WordPress CSS classes in custom markup and even by replicating the CSS from scratch.

howtosplash5501

In this article, we’ll see how WordPress provides functionality that can be used to generate native admin tables. We’ll look at a typical WordPress table and its different components and show how to implement it the right way.

Presentation Of A WordPress Table

To better understand the various elements we’ll be talking about, let’s take the default link manager that you see when you click “Links” in the admin menu. Here’s what you see:

The default page for managing links in WordPress 3.2.2
The default page for managing links in WordPress 3.2.

As you can see, a few different elements precede the table that enable you to perform actions on the table. Then we have the table’s header, the rows, the table’s footer and, finally, some more actions.

Before and After the Table

WordPress’ admin interface is consistent, so you’ll get used to finding elements in certain places as you navigate.

Before and after the admin tables, for example, are where you would usually find options to take action on the table. These include bulk actions, which enable you to edit and delete multiple posts and to filter the list based on a certain criteria.

We’ll see in the second part of this article how to interact with these two areas and how to display options there.

Header and Footer

Speaking of consistency, every admin table in WordPress has a header and footer.

Following the same logic, they display the the same information: the titles of the columns. Some of the titles are simple and some are linked (meaning that the table can be ordered according to that column).

The Content

Obviously, the reason you would create a table is to put some content in it. This content would go in the rows between the header and footer.

How Is This Done In WordPress?

As we’ve just seen, a WordPress table has three families of elements. Let’s see how to achieve this, using a concrete example.

Our Example Table

Most of the time, the data we want to display will be in the form of a SQL table. We’ll use the default links table in WordPress as our example, but the concepts apply to any database table and could easily be adapted to your needs. Our table will have the following structure:

Structure of the links table3

This table contains some default data that will be perfect for testing.

Using the List Table Class

To create an HTML table in WordPress, we don’t have to write a lot of HTML. Instead, we can rely on the precious work of the WP_List_Table class. As explained by the WordPress Codex4, this class is a powerful tool for generating tables.

It is tailored for back-end developers, so we can concentrate on the most essential task (the treatment of the data), leaving the other tasks (such as HTML rendering) to WordPress.

The WP_List_Table class is essentially a little framework whose functionality we can rely on to prepare our table. This is an object-oriented approach, because we’ll be creating an object that extends WP_List_Table and using that, instead of using WP_List_Table directly.

Let’s create a class Link_List_Table with a simple constructor:

class Link_List_Table extends WP_List_Table {

   /**
    * Constructor, we override the parent to pass our own arguments
    * We usually focus on three parameters: singular and plural labels, as well as whether the class supports AJAX.
    */
    function __construct() {
       parent::__construct( array(
      'singular'=> 'wp_list_text_link', //Singular label
      'plural' => 'wp_list_test_links', //plural label, also this well be one of the table css class
      'ajax'   => false //We won't support Ajax for this table
      ) );
    }

}

This is the starting point of our table. We now have an object that has access to the properties and methods of its parent, and we’ll customize it to suit our needs.

Keeping in mind the three types of elements we saw earlier, let’s see now what to add to our class to get the same result.

How to Add Elements Before and After the Table

To display content before or after the table, we need to add a method named extra_tablenav to our class. This method can be implemented as follows:

/**
 * Add extra markup in the toolbars before or after the list
 * @param string $which, helps you decide if you add the markup after (bottom) or before (top) the list
 */
function extra_tablenav( $which ) {
   if ( $which == "top" ){
      //The code that goes before the table is here
      echo"Hello, I'm before the table";
   }
   if ( $which == "bottom" ){
      //The code that goes after the table is there
      echo"Hi, I'm after the table";
   }
}

The interesting thing here is that the extra_tablenav method takes one parameter, named $which, and this function is called twice by Link_List_Table, (once before the table and once after). When it’s called before, the value of the $which parameter is top, and when it’s called a second time, after the table, its value is bottom.

You can then use this to position the various elements that you’d like to appear before and after the table.

This function exists in the parent WP_List_Table class in WordPress, but it doesn’t return anything, so if you don’t override it, nothing bad will happen; the table just won’t have any markup before or after it.

How to Prepare the Table’s Header and Footer

In the header and footer, we have the column’s headers, and some of them are sortable.

We’ll add to our class a method named get_columns that is used to define the columns:

/**
 * Define the columns that are going to be used in the table
 * @return array $columns, the array of columns to use with the table
 */
function get_columns() {
   return $columns= array(
      'col_link_id'=>__('ID'),
      'col_link_name'=>__('Name'),
      'col_link_url'=>__('Url'),
      'col_link_description'=>__('Description'),
      'col_link_visible'=>__('Visible')
   );
}

The code above will build an array in the form of 'column_name'=>'column_title'. This array would then be used by your class to display the columns in the header and footer, in the order you’ve written them, so defining that is pretty straightforward.

Plenty of fields are in the links table, but not all of them interest us. With our get_columns method, we’ve chosen to display only a few of them: the ID, the name, the URL, the description of the link, as well as whether the link is visible.

Unlike the extra_tablenav method, the get_columns is a parent method that must be overridden in order to work. This makes sense, because if you don’t declare any columns, the table will break.

To specify the columns to which to add sorting functionality, we’ll add the get_sortable columns method to our class:

/**
 * Decide which columns to activate the sorting functionality on
 * @return array $sortable, the array of columns that can be sorted by the user
 */
public function get_sortable_columns() {
   return $sortable = array(
      'col_link_id'=>'link_id',
      'col_link_name'=>'link_name',
      'col_link_visible'=>'link_visible'
   );
}

Here again, we’ve built a PHP array. The model for this one is 'column_name'=>'corresponding_database_field'. In other words, the column_name must be the same as the column name defined in the get_columns method, and the corresponding_database_field must be the same as the name of the corresponding field in the database table.

The code we have just written specifies that we would like to add sorting functionality to three columns (“ID,” “Name” and “Visible”). If you don’t want the user to be able to sort any columns or if you just don’t want to implement this method, WordPress will just assume that no columns are sortable.

At this point, our class is ready to handle quite a few things. Let’s look now at how to display the data.

How to Display the Table’s Rows

The first steps in preparing the list table are very quick. We just have to tackle a few more things in the treatment of data.

To make the list table display your data, you’ll need to prepare your items and assign them to the table. This is handled by the prepare_items method:

/**
 * Prepare the table with different parameters, pagination, columns and table elements
 */
function prepare_items() {
   global $wpdb, $_wp_column_headers;
   $screen = get_current_screen();

   /* -- Preparing your query -- */
        $query = "SELECT * FROM $wpdb->links";

   /* -- Ordering parameters -- */
       //Parameters that are going to be used to order the result
       $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; }

   /* -- Pagination parameters -- */
        //Number of elements in your table?
        $totalitems = $wpdb->query($query); //return the total number of affected rows
        //How many to display per page?
        $perpage = 5;
        //Which page is this?
        $paged = !empty($_GET["paged"]) ? mysql_real_escape_string($_GET["paged"]) : '';
        //Page Number
        if(empty($paged) || !is_numeric($paged) || $paged<=0 ){ $paged=1; }
        //How many pages do we have in total?
        $totalpages = ceil($totalitems/$perpage);
        //adjust the query to take pagination into account
       if(!empty($paged) && !empty($perpage)){
          $offset=($paged-1)*$perpage;
         $query.=' LIMIT '.(int)$offset.','.(int)$perpage;
       }

   /* -- Register the pagination -- */
      $this->set_pagination_args( array(
         "total_items" => $totalitems,
         "total_pages" => $totalpages,
         "per_page" => $perpage,
      ) );
      //The pagination links are automatically built according to those parameters

   /* -- Register the Columns -- */
      $columns = $this->get_columns();
      $_wp_column_headers[$screen->id]=$columns;

   /* -- Fetch the items -- */
      $this->items = $wpdb->get_results($query);
}

As you can see, this method is a bit more complex than the previous ones we added to our class. So, let’s see what is actually happening here:

  1. Preparing the query
    The first thing to do is specify the general query that will return the data. Here, it’s a generic SELECT on the links table.
  2. Ordering parameters
    The second section is for the ordering parameters, because we have specified that our table can be sorted by certain fields. In this section, we are getting the field (if any) by which to order our record ($_GET['order']) and the order itself ($_GET['orderby']). We then adjust our query to take those into account by appending an ORDER BY clause.
  3. Pagination parameters
    The third section deals with pagination. We specify how many items are in our database table and how many to show per page. We then get the current page number ($_GET['paged']) and then adapt the SQL query to get the correct results based on those pagination parameters.
  4. Registration
    This part of the function takes all of the parameters we have prepared and assigns them to our table.
  5. Ready to go
    Our list table is now set with all of the information it needs to display our data. It knows what query to execute to get the records from the database; it knows how many records will be returned; and all the pagination parameters are ready. This is an essential method of your list table class. If you don’t implement it properly, WordPress won’t be able to retrieve your data. If the method is missing in your class, WordPress will return an error telling you that the prepare_items method must be overridden.
  6. Displaying the rows
    This is it! Finally, we get to the method responsible for displaying the records of data. It is named display_rows and is implemented as follows.
/**
 * Display the rows of records in the table
 * @return string, echo the markup of the rows
 */
function display_rows() {

   //Get the records registered in the prepare_items method
   $records = $this->items;

   //Get the columns registered in the get_columns and get_sortable_columns methods
   list( $columns, $hidden ) = $this->get_column_info();

   //Loop for each record
   if(!empty($records)){foreach($records as $rec){

      //Open the line
        echo '< tr id="record_'.$rec->link_id.'">';
      foreach ( $columns as $column_name => $column_display_name ) {

         //Style attributes for each col
         $class = "class='$column_name column-$column_name'";
         $style = "";
         if ( in_array( $column_name, $hidden ) ) $style = ' style="display:none;"';
         $attributes = $class . $style;

         //edit link
         $editlink  = '/wp-admin/link.php?action=edit&link_id='.(int)$rec->link_id;

         //Display the cell
         switch ( $column_name ) {
            case "col_link_id":  echo '< td '.$attributes.'>'.stripslashes($rec->link_id).'< /td>';   break;
            case "col_link_name": echo '< td '.$attributes.'>'.stripslashes($rec->link_name).'5< /td>'; break;
            case "col_link_url": echo '< td '.$attributes.'>'.stripslashes($rec->link_url).'< /td>'; break;
            case "col_link_description": echo '< td '.$attributes.'>'.$rec->link_description.'< /td>'; break;
            case "col_link_visible": echo '< td '.$attributes.'>'.$rec->link_visible.'< /td>'; break;
         }
      }

      //Close the line
      echo'< /tr>';
   }}
}

This function gets the data prepared by the prepare_items method and loops through the different records to build the markup of the corresponding table row.

With this method, you have great control over how to display the data. If you do not wish to add this method to your class, then the class will use the parent’s method to render the data in WordPress’ default style.

Your list table class is now finished and ready to be used on one of your pages.

All of the methods we’ve added to our class already exist in the parent WP_List_Table class. But for your child class to work, you must override at least two of them: get_columns and prepare_items.

Implementation

Now that our list table class is ready, let’s see how we can use it on a page of our choice.

Where Do We Write It?

The code that we’ll cover in this section has to be written on the page where you want to display the admin table.

We’ll create a very simple demonstration plugin, named “Test WP List Table.” Basically, this plugin will add a link in the WordPress “Plugins” sub-menu. Our code will, therefore, be written in the plugin file.

Before We Begin

Important: the WP_List_Table class is not available in plugins by default. You can use the following snippet to check that it is there:

//Our class extends the WP_List_Table class, so we need to make sure that it's there
if(!class_exists('WP_List_Table')){
   require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
}

Also, if you have created your Links_List_Table class in an external file, make sure to include it before you start instantiating.

Instantiate the Table

The first step is to create an instance of our list table class, then call the prepare_items method to fetch the data to your table:

//Prepare Table of elements
$wp_list_table = new Links_List_Table();
$wp_list_table->prepare_items();

Display It

The $wp_list_table object is now ready to display the table wherever you want.

Build your page’s markup, and wherever you decide to display the table, make a call to the display() method:

//Table of elements
$wp_list_table->display();

Calling the display() method will generate the full markup of the list table, from the before-and-after area to the table’s content, and including the table’s header and footer. It also automatically generates all pagination links for you, so the result should look like this:

6

In the download accompanying this article, you’ll find the complete PHP file containing the class definition and the example of its implementation. It is named testWPListTable.php, and it is written in the form of a simple plugin that you can put in your WordPress plugin folder and activate if you want to see what it does.

Conclusion

Creating a PHP class merely to display a table of data might seem like overkill. But this class is very easy to create and customize. And once it’s done, you’ll be happy that the parts of tables that are difficult to implement, such as pagination and reordering, are now taken care of.

Also, because the generated markup is exactly what WordPress supports, if an update is released one day, your tables will remain in good shape.

The PHP code we’ve used is clean and easy to understand. And mastering the default functionality won’t take a long time.

What we’ve seen today is the basic implementation of a WordPress list table, but you can add other supported methods to the class for extra functionality.

For more information, read the Codex page dedicated to WordPress list tables7, and have a look at another custom list table example8.

I hope you’ve found this article useful, and I wish you good luck with list tables!

(al)

↑ Back to topShare on Twitter

Passionate web developer from Lyon. Jeremy likes to build sweet & strong web apps, usually based on PHP. WordPress nerd, he loves jQuery, tweets about web development, blogs at jdmweb, and works at NOE interactive.

  1. 1

    Awesome post – first!

    2
  2. 2

    Couldn’t have come at a better time. Doing my first theme with an admin panel page.

    Thanks Broski.

    I’m second Brah!!!

    0
  3. 3

    Really good and thoroughly explained!

    Just my 2 cents:

    You don’t need to implement the complicated function display_rows(). There is a much easier way to do it. You can create functions named column_columname($item). For example:

    function column_col_link_name($item){
    return $item->link_name;
    }

    If you define a function like this for each column, WordPress will iterate all the data and show (and style!) each row automatically. Much much cleaner. Also, you can have a: function column_default($item) as a fallback.

    For inserting the action links (like “edit”, “delete”), you can use row_actions this way:

    function column_col_link_name($item){
    $actions = array(
    ‘delete’ => sprintf(‘Delete it‘,$_REQUEST['page'],’delete’,$item->ID),
    ‘view’ => sprintf(‘View‘,get_permalink($item->ID)));

    return “ID, true ) . “‘>”. $item->post_title .” ” . $this->row_actions($actions);
    }

    6
  4. 4

    What’s I’m looking for. Thanks.

    0
  5. 5

    It print out this :

    Fatal error: Call to undefined method Link_List_Table::column_default() in D:EasyPHP-5.3.2wwwwordpresswp-adminincludesclass-wp-list-table.php on line 855

    what should i do?

    1
  6. 7

    When using this, we get a “wp_parse_args” function is undefined directly coming from class-wp-list-table.php

    Also;

    $wp_list_table = new Links_List_Table();
    $wp_list_table->prepare_items();

    Should be:

    $wp_list_table = new Link_List_Table();
    $wp_list_table->prepare_items();

    0
    • 8

      Update! I’ve had to do a little bit to fix some missing includes etc (which is relevant to the location of my theme admin panel):

      include ‘../../../../../../wp-load.php’;
      if ( file_exists( ABSPATH . ‘wp-config.php’) ) {
      require_once( ABSPATH . ‘wp-config.php’ );
      }

      require_once( ABSPATH . ‘wp-admin/includes/screen.php’ );

      0
  7. 9

    This article couldn’t be more perfectly timed.

    Here’s the rub: how would you use this class to override the admin table for the default Posts? The plug-in I created heavily customizes the Posts menu and I’d like to separate out posts into different admin tables according to a custom meta keys. For example, say I want to create two tables: one for internal listings (meta key “listing”, meta value “internal”) and one for courtesy listings (meta key “listing”, meta value “courtesy”). Is it possible to do this with this class?

    0
  8. 10

    Andres Hermosilla

    November 15, 2011 3:20 pm

    You mentioned a download for the final file for reference, where can I find it?

    11
  9. 11

    Great article!

    Just what I was looking for, but as James said; please fix the class name in your call, but also tr/td tags has a space in them.

    0
  10. 12

    *Super Awesome* This was VERY helpful. Y’all are great. (hug)

    If i want to put same functionality on my Template page in my selected theme or other then admin panel, What would to do?

    1
  11. 14

    Just a question. If I want to display and eventually manage data from a table in a different db from the wordpress installation one (for example another db in the same mysql database) how can I set this different connection??
    I have to build a site for makes some user able to read (only read!!) and sort data from a db and I’m thinking about building it with wordpress…

    Thank you, really

    0
  12. 15

    I believe there’s a typo in the ‘Instantiate’ part. The class name is wrong, it should read $wp_list_table = new Link_List_Table();

    0
  13. 16

    Nice tutorial, only:

    list( $columns, $hidden ) = $this->get_column_info();

    does not return anything…?

    3
    • 17

      Replace:
      /* — Register the Columns — */
      $columns = $this->get_columns();
      $_wp_column_headers[$screen->id]=$columns;

      With:
      /* — Register the Columns — */
      $columns = $this->get_columns();
      $hidden = array();
      $sortable = $this->get_sortable_columns();
      $this->_column_headers = array($columns, $hidden, $sortable);

      15
      • 18

        Bless you. Thank you for this fix, and thanks to the rest of the commenters for helping each other fix the many mistakes in this code.

        Nevertheless, thanks to Jeremy for starting the conversation and explaining things so well.

        2
  14. 19

    This is a nice key to develop more standard interface for plugins in WordPress.
    Any tips of more to read about this hidden feature in WP? There are few posts about WP-List-Table out there. This Smashing article is the best so far!

    0
  15. 20

    Regarding get_sortable_columns() it is important to follow the instructions:
    * Get a list of sortable columns. The format is:
    * ‘internal-name’ => array( ‘orderby’, true )
    * The second format will make the initial sorting order be descending
    So an example:
    public function get_sortable_columns() {
    return $sortable = array(
    ‘name’ => array(‘name’,true),
    ‘department’ => array(‘department’, true)
    );
    }

    4
  16. 22

    According to WordPress you should prepare the column like this:
    $columns = $this->get_columns();
    $hidden = array();
    $sortable = $this->get_sortable_columns();
    $this->_column_headers = array($columns, $hidden, $sortable);

    …instead of

    /* — Register the Columns — */
    $columns = $this->get_columns();
    $_wp_column_headers[$screen->id]=$columns;

    Otherwise you get the same error as Sven den Otter in the comments above.

    4
  17. 23

    Thank you it was really helpful for me.
    I have a suggestion, you could use $this->get_pagenum(); within the prepare method. Then you don’t have to check for the pagination since WordPress does it for you.

    0
    • 24

      I was having the same probelm about a month back. Your solution is better than mine $wp_query = new WP_Query();$paged = (get_query_var( paged’)) ? get_query_var( paged’) : 1;$wp_query->query( orderby=post_date&order=DESC&paged=’ . $paged);Then to draw the pagination I had..max_num_pages); ?>The reason I had to pass a 2nd param was cause for some reason the next_posts_link function was not tallying max_num_pages properly (even after the function globals the $wp_query var) Passing it in directly seemed to work.Thanks for the tip!

      0
  18. 25

    Awesome article! Thanks for this great post…

    If someone is using WP 3.3.1, this will probably fail..
    Take a look at: http://wordpress.org/extend/plugins/custom-list-table-example/

    0
    • 26

      You rock!

      Simply the best to use, and completely without errors php or in wp_debug mode.

      Thank you very very much!

      0
      • 27

        Just one question though,

        Is it the idea to rewrite the class for every table you want to generate?
        For example if if i have 2 pages with a table in my plugin?

        Or to pass say a query to it so it outputs the think you want, and you only write the entire class once?

        0
  19. 28

    i recieve this message please any body suggest me what i have to do now

    function WP_List_Table::get_columns() must be over-ridden in a sub-class

    0
  20. 30

    Very nice tutorial and extremely usefull !! Thanks ! :)

    1
  21. 31

    Heey, where is input search links?????

    :(

    -1
  22. 32

    Sweet!
    Saved me a lot of time…
    Thanks!

    0
  23. 33

    Anyone have an example of using the plug-in version that actually queries the database? and another example of using the search feature? I want to try to list all my site users and can’t figure out how to do this.

    0
  24. 34

    Is it just me or does the article miss a link to the example code?

    “In the download accompanying this article, you’ll find the complete PHP file containing the class definition and the example of its implementation. It is named testWPListTable.php”

    4
  25. 35

    I have followed this to a tee, however when I look at the output, the column heads have the href “orderby=t” or “orderby=i” where t and i should be “title” and “id” respectively. Any idea what could be causing this?

    Thank you so much for this great article, it helped immensely!

    0
    • 36

      /facepalm

      public function get_sortable_columns(){
      //”col_id” => “id”,
      “col_id” => array(“id”),

      }

      0
  26. 37

    Has anyone got the testWPListTable.php they can send me?

    0
  27. 38

    This tutorial is out of date. There have been a few changes to the class. I believe in the comments there is most of the changes. This article could probably be edited to have the new updates.

    0
  28. 39

    Is there an example of the function that will handle the row specific edit,delete actions. I can’t see from the base class how this should be done.

    0
  29. 40

    Does anyone have an idea how to pass another argument to the pagination?

    I’d like to have something like this: ?page=my_adminpage&paged=1&s=your_searchphrase, but only if stlen($your_searchphrase) > 0.

    Beside this: brilliant tutorial. I’ve learned a lot about listing database entries in the backend ;-)

    0
  30. 41

    I would love a simple way of adding a function so that say if a status checkbox ( three columns and each being a selectable status with a radio button type checkbox ( only one selected at a time ) ( i.e., in progress, almost done, and done) when a checkbox is clicked then the user/email (the email will be another field in the same row ) is then emailed with new status of that row/data…

    0
  31. 42

    The code for adding ORDER BY to the query in prepare_items() is wrong.

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

    The above code, taken from this tutorial, will result in something like “SELECT * FROM `table` WHERE `column1`=’`value’ ORDER BY ASC `column2`”.
    The fix is to simply delete ASC from the $orderby line and put it in the same place in the $order line instead.

    0
  32. 43

    i just got this error!

    function WP_List_Table::prepare_items() must be over-ridden in a sub-class.

    0
  33. 44

    This is the code with the last corrections

    http://pastebin.com/h7u7DP1Y

    4
  34. 45

    It’s really a wonderful article. I love it. It works for me. I want to add search option. Could you give an idea to implement search option in my table.

    Thanks in advance

    0
  35. 46

    Thanks for this guidelines..

    0
  36. 47

    Hi, I don’t know if this article is up to date.
    Thank you very much for this nice tutorial.

    Is it possible to have an actual example on how to edit a single row item?
    I mean, clicking on the “edit” action on a single item, which code I should add to the class to actually show an edit form (with all the actual values already in place?).

    0
  37. 48

    Can you please please explaining what made you write those HTML tags with a leading space

    Is it even valid HTML?

    0
  38. 49

    Can i give a kiss to you ??? ;)

    Well Written.Thank you so much for your time.

    0
  39. 50

    can any one please suggest how to get content in between header and footer.

    0
  40. 51

    that’s what i want..thank for writing this..
    but i have some problem when i try to make my own table..in row action i make an ‘Edit’ link just like the tutorials says,,like this..

    function column_pertanyaan($item){
    $actions = array(
    ‘edit’ => sprintf(‘Edit‘,$_REQUEST['page'],’edit’,$item->ID),
    ‘delete’ => sprintf(‘Delete‘,$_REQUEST['page'],’delete’,$item->ID),
    );
    return sprintf(‘%1$s %2$s’, $item->pertanyaan, $this->row_actions($actions) );
    }

    how about if i make a function quiz_edit() for editing process,,i make it in quiz-edit.php file..can i call that function with ‘Edit’ link??
    i’ve tried to use
    sprintf(‘Edit‘,’quiz-edit’,’edit’,$item->ID)
    and sprintf(‘Edit‘,’quiz-edit.php’,’edit’,$item->ID)
    and sprintf(‘Edit‘,my-plugin/quiz-edit.php,’edit’,$item->ID)
    and all of them just give me the same result,,”You do not have sufficient permissions to access this page.”..
    maybe you can suggest me what to do..
    thanks before.. :)

    0
  41. 52

    My data rows are displayed outside of the tbody tag. What am I missing?

    0
  42. 53

    I realize that this article was published in 2011 but maybe you should update it to add a short notice about the fact that this class is (now) marked as private and the WordPress team discourages developers from using it in plugins and themes.

    You can see this notice on the official documentation page to which you provide a link (see the red paragraph at the top). Even if at least for now it works they do reserve the right to make fundamental changes to it causing plugins that use it to malfunction.

    Considering that there is no suggested alternative I am curious if anyone found an “orthodox” way to create lists in the admin area.

    1
  43. 54

    That’s a very nice post! Hopefully this will work with WP 3.6.1!

    Edit: Just seen Mishu comment, looks like it dont >.<

    0
  44. 55

    hello im niranjana. First of all im new to WordPress and im developing a custom plugin.I have the code like same as above list table but little difference. The problem is I cant see all the data. I think it’s page pagination matter. but I can’t figure if out.when I go to last page my last row couldn’t see. final rows are missing.Please help me. Email me

    function prepare_items() {
    global $wpdb;
    $table_name = $wpdb->prefix . ‘cts_posts’; // do not forget about tables prefix

    $per_page = 4; // constant, how much records will be shown per page

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

    // here we configure table headers, defined in our methods
    $this->_column_headers = array($columns, $hidden, $sortable);

    // [OPTIONAL] process bulk action if any
    $this->process_bulk_action();

    // will be used in pagination settings
    $total_items = $wpdb->get_var(“SELECT COUNT(id) FROM $table_name”);

    // prepare query params, as usual current page, order by and order direction
    $paged = isset($_REQUEST['paged']) ? max(0, intval($_REQUEST['paged']) – 1) : 0;
    $orderby = (isset($_REQUEST['orderby']) && in_array($_REQUEST['orderby'], array_keys($this->get_sortable_columns()))) ? $_REQUEST['orderby'] : ‘id’;
    $order = (isset($_REQUEST['order']) && in_array($_REQUEST['order'], array(‘asc’, ‘desc’))) ? $_REQUEST['order'] : ‘asc’;

    // [REQUIRED] define $items array
    // notice that last argument is ARRAY_A, so we will retrieve array
    $this->items = $wpdb->get_results($wpdb->prepare(“SELECT * FROM $table_name ORDER BY $orderby $order LIMIT %d OFFSET %d”, $per_page, $paged), ARRAY_A);

    // [REQUIRED] configure pagination
    $this->set_pagination_args(array(
    ‘total_items’ => $total_items, // total items defined above
    ‘per_page’ => $per_page, // per page constant defined at top of method
    ‘total_pages’ => ceil($total_items / $per_page) // calculate pages count
    ));
    }

    }

    0
  45. 56

    I am new in word press please help me .
    I just put the above code snippet to my custom plugin but I am getting only tr tags (opening and closing) Doesn’t not display tables where is my table ? anyone help me to correct this ? ?

    0
  46. 57

    I am new to wordpress please help.
    I just put this whole file in plugin folder , and then activate the plugin and i click on “WP List Table Test” link so it does not showing the columns of “wp_links” table, it only showing just “no items found” message without any columns to show
    please helpppp

    0
  47. 58

    i’m new in wordpress please help
    how to implement the wp_list_table edit/delete actions , actually i want to edit/delete the details of the row also from my database table

    0
  48. 59

    Gregory Lancaster

    March 3, 2014 11:34 am

    This code creates a table, but it spans to the far right. It should have padding on the right of it. Not sure its completely correct.

    0
  49. 60

    Very nice! Thank you.
    I got inspiration from this article!

    Thanks again.

    0

Leave a Comment

Yay! You've decided to leave a comment. That's fantastic! Please keep in mind that comments are moderated and rel="nofollow" is in use. So, please do not use a spammy keyword or a domain as your name, or else it will be deleted. Let's have a personal and meaningful conversation instead. Thanks for dropping by!

↑ Back to top