Как добавить WP_List_Table на страницу WordPress?
У меня есть WP_List_Table, и я хочу добавить её на страницу, но в поисках не нашёл примеров, как это сделать. У кого-нибудь есть готовый пример кода для реализации этой задачи?
<?php
/*
Plugin Name: Add Parl Plugin 2
Description: Плагин для добавления парламентов
Plugin URI: "http://www.ttparliaments.org"
Author URI: ""
Author: Napoleon Okunna
License: ""
Version: 1.0
*/
global $custom_table_example_db_version;
$custom_table_example_db_version = '1.1'; // версия изменена с 1.0 на 1.1
global $wpdb;
global $custom_table_example_db_version;
$table_name = $wpdb->prefix . 'oop_parliamentary_info'; // не забываем про префикс таблиц
/**
* ЧАСТЬ 2. Определение кастомного списка таблиц
* ============================================================================
*
* В этой части мы определяем класс кастомной таблицы,
* который будет отображать записи из БД в виде удобной таблицы
*
* http://codex.wordpress.org/Class_Reference/WP_List_Table
* http://wordpress.org/extend/plugins/custom-list-table-example/
*/
if (!class_exists('WP_List_Table')) {
require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
}
/**
* Класс Custom_Table_Example_List_Table для отображения
* записей нашей кастомной таблицы
*/
class Custom_Table_Example_List_Table extends WP_List_Table
{
/**
* [ОБЯЗАТЕЛЬНО] Объявляем конструктор и задаём базовые параметры
*/
function __construct()
{
global $status, $page;
parent::__construct(array(
'singular' => 'person',
'plural' => 'persons',
));
}
/**
* [ОБЯЗАТЕЛЬНО] Стандартный рендерер колонок
*
* @param $item - строка (массив ключ-значение)
* @param $column_name - строка (ключ)
* @return HTML
*/
function column_default($item, $column_name)
{
return $item[$column_name];
}
/**
* [ОПЦИОНАЛЬНО] Пример рендеринга конкретной колонки
*
* имя метода должно быть вида: "column_[имя_колонки]"
*
* @param $item - строка (массив ключ-значение)
* @return HTML
*/
function column_age($item)
{
return '<em>' . $item['age'] . '</em>';
}
/**
* [ОПЦИОНАЛЬНО] Пример рендеринга колонки с действиями
* при наведении показываются ссылки "Редактировать | Удалить"
*
* @param $item - строка (массив ключ-значение)
* @return HTML
*/
function column_name($item)
{
$actions = array(
'edit' => sprintf('<a href="?page=%s&action=%s&book=%s">Редактировать</a>',$_REQUEST['page'],'edit',$item['ParliamentaryID']),
'delete' => sprintf('<a href="?page=%s&action=%s&book=%s">Удалить</a>',$_REQUEST['page'],'delete',$item['ParliamentaryID']),
);
return sprintf('%1$s %2$s', $item['booktitle'], $this->row_actions($actions) );
}
/**
* [ОБЯЗАТЕЛЬНО] Рендеринг колонки с чекбоксами
*
* @param $item - строка (массив ключ-значение)
* @return HTML
*/
function column_cb($item)
{
return sprintf(
'<input type="checkbox" name="id[]" value="%s" />',
$item['id']
);
}
/**
* [ОБЯЗАТЕЛЬНО] Метод возвращает колонки для отображения в таблице
* можно пропустить колонки, которые не нужно показывать
* например, содержание или описание
*
* @return array
*/
function get_columns()
{
$columns = array(
'cb' => '<input type="checkbox" />', // Рендерим чекбокс вместо текста
'Title' => __('Title', 'custom_table_example'),
'StartDate' => __('StartDate', 'custom_table_example'),
'EndDate' => __('EndDate', 'custom_table_example'),
'IsCurrent' => __('IsCurrent', 'custom_table_example'),
ParliamentaryID =>'<a href=#>Редактировать</a>',
);
return $columns;
}
/**
* [ОПЦИОНАЛЬНО] Метод возвращает колонки, по которым можно сортировать таблицу
* все строки в массиве - имена колонок
* true у колонки name означает, что сортировка по ней включена по умолчанию
*
* @return array
*/
function get_sortable_columns()
{
$sortable_columns = array(
'Title' => array('Title', true),
'StartDate' => array('StartDate', false),
'EndDate' => array('EndDate', false),
'IsCurrent' => __('IsCurrent', false),
'ParliamentaryID'=> __('ParliamentaryID', false),
);
return $sortable_columns;
}
/**
* [ОПЦИОНАЛЬНО] Возвращает массив групповых действий, если они есть
*
* @return array
*/
function get_bulk_actions()
{
$actions = array(
'delete' => 'Удалить',
'edit' =>'Редактировать'
);
return $actions;
}
/**
* [ОПЦИОНАЛЬНО] Метод обрабатывает групповые действия
* может быть вне класса
* нельзя использовать wp_redirect, так как вывод уже начат
* в этом примере мы обрабатываем действие удаления
* сообщение об успешном удалении будет показано на странице в следующей части
*/
function process_bulk_action()
{
global $wpdb;
$table_name = $wpdb->prefix . 'cte'; // не забываем про префикс таблиц
if ('delete' === $this->current_action()) {
$ids = isset($_REQUEST['id']) ? $_REQUEST['id'] : array();
if (is_array($ids)) $ids = implode(',', $ids);
if (!empty($ids)) {
$wpdb->query("DELETE FROM $table_name WHERE id IN($ids)");
}
}
if ('Edit' === $this->current_action()) {
echo('Редактировать');
}
}
/**
* [ОБЯЗАТЕЛЬНО] Самый важный метод
*
* Получает строки из БД и подготавливает их для отображения в таблице
*/
function prepare_items()
{
global $wpdb;
$table_name = $wpdb->prefix . 'cte'; // не забываем про префикс таблиц
$table_name='oop_parliamentary_info';
$per_page = 5; // константа, сколько записей показывать на странице
$columns = $this->get_columns();
$hidden = array();
$sortable = $this->get_sortable_columns();
// конфигурируем заголовки таблицы, определённые в наших методах
$this->_column_headers = array($columns, $hidden, $sortable);
// [ОПЦИОНАЛЬНО] обрабатываем групповые действия, если они есть
$this->process_bulk_action();
// используется для настроек пагинации
$total_items = $wpdb->get_var("SELECT COUNT(ParliamentaryID) FROM $table_name");
// подготавливаем параметры запроса: текущая страница, сортировка и направление
$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'] : 'name';
$order = (isset($_REQUEST['order']) && in_array($_REQUEST['order'], array('asc', 'desc'))) ? $_REQUEST['order'] : 'asc';
// [ОБЯЗАТЕЛЬНО] определяем массив $items
// последний аргумент ARRAY_A означает, что мы получаем массив
$this->items = $wpdb->get_results($wpdb->prepare("SELECT Title,StartDate,EndDate,ParliamentaryID FROM oop_parliamentary_info ", $per_page, $paged), ARRAY_A);
// перебираем элементы и форматируем строки
foreach ($this->items as $item ) {
static $row_class = '';
$row_class = ( $row_class == '' ? ' class="alternate"' : '' );
echo '<tr' . $row_class . '>';
echo '</tr>';
}
// [ОБЯЗАТЕЛЬНО] настраиваем пагинацию
$this->set_pagination_args(array(
'total_items' => $total_items, // общее количество элементов
'per_page' => $per_page, // количество элементов на странице
'total_pages' => ceil($total_items / $per_page) // вычисляем количество страниц
));
}
function single_row_columns($item) {
list($columns, $hidden) = $this->get_column_info();
foreach ($columns as $column_name => $column_display_name) {
$class = "class='$column_name column-$column_name'";
$style = '';
if (in_array($column_name, $hidden))
$style = ' style="display:none;"';
$attributes = "$class$style";
if ('cb' == $column_name) {
echo "<td $attributes>";
echo "</td>";
}
elseif ('ParliamentaryID' == $column_name) {
echo "<td $attributes>";
echo '<a href="#">', '';
echo "</a>";
echo "<div class='row-actions'><span class='edit'>";
echo sprintf('<a class="editParlRow" href="?page=%s&action=%s&gid=%s">Редактировать</a>',$_REQUEST['page'],'edit',$item['ParliamentaryID']);
echo "</span> | <span class='trash'>";
echo sprintf('<a href="?page=%s&action=%s&gid=%s">Удалить</a>',$_REQUEST['page'],'delete',$item['ParliamentaryID']);
echo "</span></div></td>";
}
else {
echo "<td $attributes>";
echo $this->column_default( $item, $column_name );
echo "</td>";
}
}
}
}

Ваша WP_List_Table будет отличаться — этот код адаптирован из WP_List_Table – пошаговое руководство и использует GIST: Пример плагина для использования класса WP_List_Table (полная версия). Вам нужно будет адаптировать свои методы, чтобы включить CSS и на фронтенде (не включено в этот ответ).
ВНИМАНИЕ :
Поскольку этот класс помечен как приватный, разработчики должны использовать его на свой страх и риск, так как этот класс может измениться в будущих версиях WordPress. Разработчикам, использующим этот класс, настоятельно рекомендуется тестировать свои плагины со всеми бета- и RC-версиями WordPress для поддержания совместимости.
ПОДГОТОВКА ФРОНТЕНДА
add_action ('init', function(){
// Если мы не в админке, мы не ожидаем загрузки этих файлов
if( ! is_admin() ){
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
require_once( ABSPATH . 'wp-admin/includes/screen.php' );
require_once( ABSPATH . 'wp-admin/includes/class-wp-screen.php' );
require_once( ABSPATH . 'wp-admin/includes/template.php' );
global $myListTable;
$myListTable = new My_Example_List_Table();
}
});
ВЫВОД
function my_render_list_page(){
global $myListTable;
echo '</pre><div class="wrap"><h2>Мой тест таблицы</h2>';
$myListTable->prepare_items();
?>
<form method="post">
<input type="hidden" name="page" value="ttest_list_table">
<?php
$myListTable->search_box( 'поиск', 'search_id' );
$myListTable->display();
echo '</form></div>';
}
НА ВАШЕЙ СТРАНИЦЕ
my_render_list_page();
СЖАТАЯ ВЕРСИЯ
function my_render_list_page(){
static $myListTable;
if( ! isset($myListTable)) {
require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
require_once(ABSPATH . 'wp-admin/includes/screen.php');
require_once(ABSPATH . 'wp-admin/includes/class-wp-screen.php');
require_once(ABSPATH . 'wp-admin/includes/template.php');
$myListTable = new My_Example_List_Table();
}
echo '</pre><div class="wrap"><h2>Мой тест таблицы</h2>';
$myListTable->prepare_items();
?>
<form method="post">
<input type="hidden" name="page" value="ttest_list_table">
<?php
$myListTable->search_box('поиск', 'search_id');
$myListTable->display();
echo '</form></div>';
}

Таким образом, вы загружаете (очень рано) 4 файла при каждом фронтенд-запросе, даже для страниц, которые не используют функцию my_render_list_page()
. Почему бы не подключить файл и не создать экземпляр класса внутри самой функции my_render_list_page()
? Это сделает код проще, читаемее и избавит от глобальных переменных...
