all07

Всего понемногу ...

Вселенский опыт говорит, что погибают царства не оттого, что тяжек быт или страшны мытарства.
А погибают оттого (и тем больней, чем дольше), что люди царства своего не уважают больше. (Булат Окуджава)

Те, кто готовы пожертвовать насущной свободой в обмен на то, чтобы получить временную безопасность, — недостойны ни свободы ни безопасности. (Бенджамин Франклин)

Война — это мир! Свобода — это рабство! Незнание — сила! (Джордж Оруэлл)

Создание таблицы с возможностью сортировки в WordPress

Эта история началась с того, что мне потребовалась таблицы для сведения сведений по моим статьям комментариев к аниме, для удобства навигации по статьям и форуму. В начале я стал использовать статические таблицы, но это оказалось совсем не гибкое и удобное решение, с учетом того что мне требовалось вносить изменения сразу в две таблицы - общую и за месяц, а также, в отдаленной перспективе, делать годовую таблицу. В результате я решил предпринять попытку несколько автоматизировать этот процесс.

После некоторых размышлений было принято, возможно не совсем изящное, но достаточно простое для моего случая решение - поместить нужные данные в специальную таблицу базы WordPress и написать плагин для выборки данных с интерфейсом через шорткод и управлять запросами через его параметры, например, ограничивать выборку данных за месяц, год или за весь период. Что у меня получилось можно посмотреть здесь.

В начале, согласно инструкции, я сделал шапку плагина, функцию регистрирующую обработчик шорткода и шаблон функции, которая будет вызываться при обнаружении шоркода из обработчика, в тексте страницы:

<?php
/*
nPlugin Name: Query Anime List
Plugin URI: http://www.all07.ru/
Description: A simple query to MySQL table to retrive it contents.
Author: all07 aka alex
Version: 0.01
Author URI: http://all07.ru
License: GPL2
*/
 
/* здесь расположен текст лицензии */
 
function q_anime_list_content( $sort = 'name', $date_from = '2012-01-01', $date_to = '2020-12-31' ) {
  $content = '';
  ob_start();
 
  echo '<p>sort = '.$sort.'; date_from = '.$date_from.'; date_to = '.$date_to.'</p>';
 
/* здесь будет код создающий html моей таблицы */
 
  $content =  ob_get_contents();
  ob_end_clean();
 
  return $content;
}
 
function q_anime_list_shortcode_handler( $atts ) {
 
  extract( shortcode_atts( array( 'sort' => 0,
                                  'date_from' => 0,
                                  'date_to' => 0,
                                ), $atts ));
 
    return q_anime_list_content( $sort, $date_from, $date_to );
}
 
add_shortcode( 'q_anime_list', 'q_anime_list_shortcode_handler');
?>
 

В нашем случае шорткод можно будет использовать таким образом: q_anime_list sort=name date_from=2012-01-01 date_to=2012-05-31 (строка должна быть заключена в квадратные скобки, но если я их поставлю, шорткод выполнится прямо на этой странице). Где q_anime_list - имя шорткода, которое регистрируется в ядре WordPress при вызове функции add_shortcode(), при этом происходит сопоставление имени шорткода с именем функции, которая будет вызвана при каждом его появлении в тексте страницы. В нашем случае это будет q_anime_list_content( $sort, $date_from, $date_to ). Для возможности управления созданием кода таблицы функции будут передаваться три параметра, значения которых можно будет задать в теле шорткода. Для случая, при кортом шорткод будет использоваться без параметров, предусмотрена установка параметров по умолчании при вызове функции.

При формировании html мы будем использовать функции для работы с буфером вывода PHP, чтобы вернуть в качестве результата уже полностью сформированный html код нашей таблицы (включая код JavaScript), который должен собою заменить шорткод на странице. Пока же, на первом этапе, для проверки правильности работы и передачи параметров, наш шорткод будет вставлять на страницу только одну тестовую строку.

Файл с текстом кода сохраняется с расширением .php и помещается в отдельную директорию, которая создается в месте расположения плагинов WordPress - wp-content/plugins/. После этого наш плагин сразу появляется в общем списке панели управления плагинами WordPress, где его необходимо активировать. После выполнения этого шага мы должны получить в качестве результата работы плагина строку при открытии страницы с шорткодом: sort = name; date_from = 2012-01-01; date_to = 2012-05-31.

Теперь пришло время создадать таблицу в базе данных WordPress в таком виде:

CREATE TABLE wp_q_anime_list 
  ( id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
    db_ref VARCHAR(255) DEFAULT NULL,           -- URL базы данных
    name VARCHAR(255) DEFAULT NULL,             -- Название аниме
    s_date DATE DEFAULT NULL,                   -- дата завершения просмотра
    anime_ep_num VARCHAR(255) DEFAULT NULL,     -- кол-во эпизодов
    anime_rel_format VARCHAR(255) DEFAULT NULL, -- тип просмотренного релиза
    anime_year YEAR(4) DEFAULT NULL,            -- год выхода
    rate SMALLINT(6) UNSIGNED DEFAULT NULL,     -- мой рейтинг
    post_link VARCHAR(255) DEFAULT NULL,        -- URL моего поста
    forum_link VARCHAR(255) DEFAULT NULL,       -- URL темы обсуждения на форуме
    PRIMARY KEY (id)
    )
    ENGINE = MYISAM
    AUTO_INCREMENT = 2
    AVG_ROW_LENGTH = 3851
    CHARACTER SET utf8
    COLLATE utf8_general_ci
    ROW_FORMAT = FIXED;
 
 

После добавления данных в созданную таблицу, напишем код запроса к базе:

  global $wpdb;
 
  $q_anime_list_table_name = $wpdb->prefix.'q_anime_list';
 
  $sql = 'SELECT name, db_ref, s_date, anime_ep_num, anime_rel_format, anime_year, \
  post_link, forum_link, rate FROM '.$q_anime_list_table_name. ' \ 
  WHERE  (s_date>="'.$date_from.'") and (s_date<="'.$date_to.'") ORDER BY name';
 
  $qal_strings = $wpdb->get_results($sql);
 

При обращении к базе данных мы используем свойства класса, доступного через переменную определенную в ядре - $wpdb, которую мы в том числе, используем для определения префикса таблиц, задаваемый при инсталляции WordPress. Хотя в моем случае можно просто было указать имя моей таблицы, так как она была создана в "ручном" режиме. В случае автоматического создании таблицы через скрипт, префикс в любом случае придется правильно определять с использованием стандартных средств.

Далее, полученные при запросе данные необходимо вставить в html код:

// id="tblm_id" будет использоваться библиотекой сортировки таблицы
echo '<table class="tblm_txt" id="tblm_id">
<col class="tblm_col_01" />
<col class="tblm_col_02" />
<col class="tblm_col_03" />
<col class="tblm_col_04" />
<col class="tblm_col_05" />
<col class="tblm_col_06" />
<col class="tblm_col_07" />
<col class="tblm_col_08" />
<thead>
  <tr>
    <th title="Сортировка по дате просмотра" class="tblm_th_l">дата</th>
    <th title="Сортировка по названию" class="tblm_th_l">название/ссылка на базу</th>
    <th title="Количество эпизодов" class="tblm_th_l">эпизоды</th>
    <th title="Тип просмотренного релиза" class="tblm_th_l">релиз</th>
    <th title="Сортировка по году выпуска">год</th>
    <th title="Сортировка по рейтингу">рейтинг</th>
    <th title="Ссылки на статьи комментариев">пост</th>
    <th title="Ссылки на темы обсуждения на форуме">форум</th>
  </tr>
<tbody>';
 
  // выводим строки таблицы
  foreach( $qal_strings as $r ) {
 
    $date_convert = date( 'd.m.y', strtotime( $r->s_date ));
 
    echo '<tr class="tblm_height"><td title="дата завершения просмотра"><span class="sp_hid">'.$r->s_date.'-</span>'.$date_convert.'</td>';
    echo '<td><a title="Информация о аниме &amp;quot;'.$r->name.'&amp;quot; на AniDB.net" href="'.$r->db_ref.'" target="_blank">'.$r->name.'</a></td>';
    echo '<td title="число эпизодов">'.$r->anime_ep_num.' эп.</td>';
    echo '<td title="формат релиза">'.$r->anime_rel_format.'</td>';
    echo '<td title="год выпуска">'.$r->anime_year.'</td>';
    echo '<td>'.$aql_rate[$r->rate].'<span class="sp_hid">'.$r->rate.'</span></td>';
    echo '<td><a title="посмотреть комментарий" href="'.$r->post_link.'" target="_blank">пост</a></td>';
    echo '<td><a title="перейти к обсуждению на форуме" href="'.$r->forum_link.'" target="_blank" title="all07.ru Форум">форум</a></td></tr>';
  }
echo '</tbody></table>';
 

Стоит сказать несколько слов для чего мне пришлось использовать теги span:

<span class="sp_hid">'.$r->s_date.'-</span>'.$date_convert

и

$aql_rate[$r->rate].'<span class="sp_hid">'.$r->rate.'</span>'
 

В этих тегах я добавляю не отображаемые в таблице данные для возможности сортировки. В первом случае - дату в виде Y:M:D, так как в таблице она будет показана в виде D:M:Y, для чего используется функция date( 'd.m.y', strtotime( $r->s_date )). Но значения таблицы в виде D:M:Y библиотека сортировки не сможет правильно отсортировать, по этому пришлось перед отображаемой частью добавить скрытую, по которой сортировка сможет правильно производится. Точно также я поступил с данными в столбце "рейтинг", в базе рейтинг хранится в виде числа, но в таблицу подставляется в виде тега img ссылающегося на картинку, по которому библиотека также не может правильно отсортировать столбец.

$aql_rate = array( '<img title="ужас! кошмар!" src="http://all07.ru/wp-content/uploads/0s.gif" alt="" width="49" height="22" />',
                   '<img title="так себе" src="http://all07.ru/wp-content/uploads/1s.gif" alt="" width="49" height="22" />',
                   '<img title="слабовато будет" src="http://all07.ru/wp-content/uploads/15s.gif" alt="" width="49" height="22" />',
                   '<img title="можно посмотреть" src="http://all07.ru/wp-content/uploads/2s.gif" alt="" width="49" height="22" />',
                   '<img title="лучше среднего" src="http://all07.ru/wp-content/uploads/25s.gif" alt="" width="49" height="22" />',
                   '<img title="отлично" src="http://all07.ru/wp-content/uploads/3s.gif" alt="" width="49" height="22" />');
 

Теперь осталось самое сложное - добавить возможность сортировки данных таблицы. Для этого я решил воспользоваться возможностями инструментария для работы таблицами DataTables, который представляет собой плагин к библиотеке JQuery, которая уже используется в работе WordPress. Для использования этого плагина необходимо подключить файлы скрипта и стилей к нашей странице с шорткодом. Эти файлы также необходимо поместить в директорию /js/ и /css/ соответственно, а также добавить в директорию /images/ картинки со стрелками, которые должны показывать порядок сортировки в шапке таблицы, которые можно найти в дистрибутиве DataTables. Для правильного подключения файлов JavaScript и CSS воспользуемся встроенными функциями WordPress:

function q_anime_list_jsscript_reg() {
wp_enqueue_script(
'jquery.dataTables',
 WP_PLUGIN_URL.'/'.str_replace(basename( __FILE__),"",plugin_basename(__FILE__)). '/js/jquery.dataTables.min.js',
array('jquery')
);
}
add_action('wp_enqueue_scripts', 'q_anime_list_jsscript_reg');
 
function q_anime_list_load_stylesheet() {
 
  wp_enqueue_style('q_anime_list_style_sheet', WP_PLUGIN_URL.'/'.str_replace(basename( __FILE__),"",plugin_basename(__FILE__)). '/css/table.css');
 
}
add_action('wp_print_styles', 'q_anime_list_load_stylesheet');
 
 

Это функции: wp_enqueue_style() и wp_enqueue_script(). Константа __FILE__ содержит полный путь к файлу скрипта, а WP_PLUGIN_URL - URL директории расположения плагинов. При регистрации скрипта плагина jquery.dataTables, в последнем параметре указывается его зависимость от скрипта jquery.

Теперь остается написать код JavaScript вызова обработчика плагина DataTables и вставить его в создаваемый html блок:

echo '<script type="text/javascript">
        var $j = jQuery.noConflict(); // необходимо для избежания конфликта с вызовами JQuery из кода ядра WP
        $j(document).ready(function() { 
          $j("#tblm_id").dataTable( { // после готовности страницы вызываем обработчик с указанием id таблицы
           "bLengthChange": false,    // убираем дроп-бокс выбора отображения числа строк таблицы на одной странице
           "bPaginate": false,        // выключаем механизм разбиения на страницы (пока не требуется)
           "bFilter": false,          // убираем строку ввода фильтра
           "bAutoWidth": false,';        // отключаем подбор ширины колонок
 
if ( $sort == 'name' ) {               // тип сортировки определяет параметр шорткода
   echo '  "aaSorting": [[1,"asc"]],'; // задаем сортировку при отображении таблицы (нумерация столбцов с "0")';
 } else {
   echo '  "aaSorting": [[0,"desc"]],';
 }
echo '
           "aoColumns": [ null,
                          null,
                         { "bSortable": false }, // запрещаем возможность сортировки по 3,4,7,8 колонкам
                         { "bSortable": false }, 
                          null,
                          null,
                         { "bSortable": false }, 
                         { "bSortable": false } ],
           "oLanguage": {                        // руссификация
                         "sInfo": "Показаны записи с _START_ по _END_ из _TOTAL_",
                         "sInfoEmpty": "Нет записей для отображения"
                        }
          } );
         $j("span").style.display="none"; // для скрытия необходимых полей для правильного отображения в долбаном IE
         // так как стили visibility: hidden; и display: none; в нем не работают.
        } );
 
</script>'; 

Немножко пришлось почитать доку к DataTables, ибо параметров настройки там достаточна много. И конечно, немного напряг факт невозможности скрыть служебные элементы в таблице стандартными средствами CSS для всех браузеров, и необходимось скрывать их отображение при помощи скрипта. После данного шага плагин находится пока еще в слишком сыром виде, но не смотря на это вполне пригоден для отображения таблицы.

Я не выкладываю весь код из-за не полной завершенности плагина. Целью статьи было показать возможность достаточно простого, "на коленке", самостоятельного написания рабочего плагина для WordPress без каких-либо глубоких знаний в области веб программирования. Также предложить некоторые решения и описать проблемы с которыми пришлось столкнуться. Конечно в этом примере показан только один из возможных способов решения поставленной задачи, но результат все же был достигнут.

В дальнейшем я планирую, рассмотреть в качестве одного из вариантов, возможность непосредственного парсинга текста статей из таблицы wp_posts на предмет выборки всех необходимых данных для полностью автоматического создания нужных индексных таблиц. Или наоборот, сделаю админку для удобного добавления и редактирования данных в используемую в этом примере таблицу, а для оформления статей буду использовать шорткоды, извлекающие эти данные. Как раз именно в такой гибкости возможных решений поставленной задачи проявляется преимущество самостоятельного написания кода, как альтернатива поиска и адаптации к своим нуждам уже готовых решений (плагинов). Надеюсь мой опыт, изложенный в этой статье сможет кому-нибудь помочь разобраться в базовых вопросах, возникающих при написании плагина.

Все замечания и предложения только приветствуются.

Еще нет комментариев к «Создание таблицы с возможностью сортировки в WordPress»

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Captcha Обновить картинку Каптчи

Пожалуйста, введите символы,
показанные внутри треугольников