Это пошаговое руководство по разработке плагинов для WordPress. В нем описываются действия, которые я выполнял при разработке реального плагина.
Описание необходимого функционала плагина
Мы создадим плагин, который будет сообщать о том, какие посты (любого типа) были опубликованы в этом календарном месяце, и кто их авторы.
Плагин для одного сайта
Я создавал этот плагин как индивидуальное решение для одного сайта. Поэтому нет необходимости делать плагин расширяемым с помощью хуков и тщательно продумывать такие моменты, как пространство имен и перевод.
Пошаговое руководство по разработке плагина для WordPress
Последовательность моих шагов:
1. Начало
<?php /** * Plugin Name: WPShout Show Authorship this Month * Description: Show who's written what this month on WPShout * Version: 1.0 * Author: WPShout * Author URI: https://wpshout.com */ add_action( 'init', 'wpshout_do_thing' ); function wpshout_do_thing() { if( ! isset( $_GET['wpsdt'] ) ) : return; endif; var_dump("Here"); die; }
Примечания к шагу 1
Этот шаг позволяет убедиться, что WordPress видит мой плагин. А также что с его помощью можно осуществлять вывод данных на экране.
Обратите внимание на строку if( ! isset( $_GET[‘wpsdt’] ) ). В ней вызывается суперглобальная переменная PHP $_GET для запуска плагина. Она задействуется тогда, когда в URL-адресе есть строка запроса wpsdt. Этот прием позволяет запускать плагин путем изменения параметров URL-адресов.
Я также подключаю событие WordPress init, чтобы плагин запускался раньше остальных. По этой же причине я назвал перехваченную функцию wpshout_do_thing(). Благодаря чему она не вызовет конфликта пространства имен.
Код var_dump(); die позволяет убедиться, что плагин выводит данные и прекращает другие процессы PHP.
Результат работы кода, приведенного выше:
2. Запрос последних записей всех типов
<?php /** * Plugin Name: WPShout Show Authorship this Month * Description: Show who's written what this month on WPShout * Version: 1.0 * Author: WPShout * Author URI: https://wpshout.com */ add_action( 'init', 'wpshout_do_thing' ); function wpshout_do_thing() { if( ! isset( $_GET['wpsdt'] ) ) : return; endif; $args = array( 'posts_per_page' => 5, 'post_type' => 'any', 'post_status' => 'publish', 'orderby' => 'date', 'order' => 'DESC', ); $query = new WP_Query( $args ); var_dump( $query ); die; }
Примечания к шагу 2
На этом шаге мы создаем пользовательский запрос WP_Query и выполняем var_dump(), чтобы убедиться, что запрос работает. Он запрашивает последние пять опубликованных записей любого типа.
В результате мы получаем объект WP_Query posts, который представляет собой массив из пяти записей.
3. Как запросить все записи, опубликованные в этом месяце
Первоначально я не знал, как это реализовать. Но затем мне удалось найти пример, в котором показывается, как передать элемент date_query массива WP_Query:
'date_query' => array( 'after' => array( 'year' => 2012, 'month' => 3, 'day' => 1, ), ),
Но как в PHP указать, что нам нужен текущий месяц? Поиск привел меня к следующему примеру:
'date_query' => array( 'after' => array( 'year' => date( 'Y' ), 'month' => date( 'M' ), 'day' => 1, ), ),
4. Объединение запроса даты с основным запросом
<?php /** * Plugin Name: WPShout Show Authorship this Month * Description: Show who's written what this month on WPShout * Version: 1.0 * Author: WPShout * Author URI: https://wpshout.com */ add_action( 'init', 'wpshout_do_thing' ); function wpshout_do_thing() { if( ! isset( $_GET['wpsdt'] ) ) : return; endif; $args = array( 'posts_per_page' => -1, 'post_type' => 'any', 'post_status' => 'publish', 'date_query' => array( 'after' => array( 'year' => date( 'Y' ), 'month' => date( 'M' ), ), 'day' => 1, ), 'orderby' => 'date', 'order' => 'DESC', ); $query = new WP_Query( $args ); var_dump( $query ); die; }
Примечания к шагу 4
На этом шаге мы добавляем параметр date_query в существующий WP_Query. А также изменяем значение posts_per_page на -1, чтобы получить все интересующие записи.
Результат выполнения приведенного выше кода:
Но этот код работает неправильно. Запрос возвращает не те записи, которые нам нужны.
5. Отладка
<?php /** * Plugin Name: WPShout Show Authorship this Month * Description: Show who's written what this month on WPShout * Version: 1.0 * Author: WPShout * Author URI: https://wpshout.com */ add_action( 'init', 'wpshout_do_thing' ); function wpshout_do_thing() { if( ! isset( $_GET['wpsdt'] ) ) : return; endif; // $args = array( // 'posts_per_page' => -1, // 'post_type' => 'any', // 'post_status' => 'publish', // 'date_query' => array( // 'after' => array( // 'year' => date( 'Y' ), // 'month' => date( 'M' ), // ), // 'day' => 1, // ), // 'orderby' => 'date', // 'order' => 'DESC', // ); // $query = new WP_Query( $args ); $after = array( 'year' => date( 'Y' ), 'month' => date( 'M' ), ); var_dump($after ); die; }
Примечания к шагу 5
На этом этапе мы выполняем следующие действия:
- Комментируем код, который ведет себя странно.
- Изучаем этот код.
Вся проблема в элементе after, который является частью массива date_query. Чтобы понять, что пошло не так, выведем информацию об этом элементе с помощью функции var_dump().
Оказывается, месяц является строкой, «Oct». А date_query может принимать только числовое значение.
6. Повторяем попытку
<?php /** * Plugin Name: WPShout Show Authorship this Month * Description: Show who's written what this month on WPShout * Version: 1.0 * Author: WPShout * Author URI: https://wpshout.com */ add_action( 'init', 'wpshout_do_thing' ); function wpshout_do_thing() { if( ! isset( $_GET['wpsdt'] ) ) : return; endif; $args = array( 'posts_per_page' => -1, 'post_type' => 'any', 'post_status' => 'publish', 'date_query' => array( 'after' => array( 'year' => date( 'Y' ), 'month' => date( 'm' ), ), 'day' => 1, ), 'orderby' => 'date', 'order' => 'DESC', ); $query = new WP_Query( $args ); // $after = array( // 'year' => date( 'Y' ), // 'month' => date( 'M' ), // ); var_dump( $query ); die; }
Примечания к шагу 6
Замени значение ‘M’ на ‘m’ в date_query. Потому что ‘m’ дает нам числовое обозначение месяца, когда он передается в date().
Запуск этого кода дает следующее:
Но это тоже не сработало. Запрос WP_Query возвратил пустой массив posts.
7. Это не сработало — отладка
<?php /** * Plugin Name: WPShout Show Authorship this Month * Description: Show who's written what this month on WPShout * Version: 1.0 * Author: WPShout * Author URI: https://wpshout.com */ add_action( 'init', 'wpshout_do_thing' ); function wpshout_do_thing() { if( ! isset( $_GET['wpsdt'] ) ) : return; endif; $args = array( 'posts_per_page' => -1, 'post_type' => 'any', 'post_status' => 'publish', 'date_query' => array( 'after' => array( 'year' => date( 'Y' ), 'month' => date( 'm' ), 'day' => 1, ), ), 'orderby' => 'date', 'order' => 'DESC', ); $query = new WP_Query( $args ); // $after = array( // 'year' => date( 'Y' ), // 'month' => date( 'M' ), // ); var_dump( $query ); die; }
Примечания к шагу 7
Ошибка заключалась в том, что я использовал day как отдельный элемент массива date_query. А нужно поместить day внутрь элемента after из date_query. Исправление и повторный запуск кода дает следующее:
В результате мы получили десять записей текущего месяца!
8. Пользовательский интерфейс и шорткод
<?php /** * Plugin Name: WPShout Show Authorship this Month * Description: Show who's written what this month on WPShout * Version: 1.0 * Author: WPShout * Author URI: https://wpshout.com */ add_shortcode( 'wpshout_show_this_months_posts_by_author', 'wpshout_show_this_months_posts_by_author' ); function wpshout_show_this_months_posts_by_author() { if( ! current_user_can( 'administrator' ) ) : return; endif; $args = array( 'posts_per_page' => -1, 'post_type' => 'any', 'post_status' => 'publish', 'date_query' => array( 'after' => array( 'year' => date( 'Y' ), 'month' => date( 'm' ), 'day' => 1, ), ), 'orderby' => 'date', 'order' => 'DESC', ); $query = new WP_Query( $args ); ob_start(); while( $query->have_posts() ) : $query->the_post(); ?> <h2><?php the_title(); ?></h2> By <?php the_author(); ?> on <?php the_date(); ?> <?php endwhile; wp_reset_postdata(); return ob_get_clean(); }
Примечания к шагу 8
Мы будем использовать шорткоды. Для этого меняем add_action() на add_shortcode() и называем функцию шорткода wpshout_show_this_months_posts_by_author(). С помощью буферизации вывода мы сможем контролировать то, какую разметку будет возвращать шорткод. Внутри цикла while() используются теги шаблонов the_author() и the_date().
Запустив плагин с помощью шорткода wpshout_show_this_months_posts_by_author, мы получаем следующее:
Но почему в одном из выведенных постов отсутствует дата?
9. THE_DATE() работает довольно странно?
<?php /** * Plugin Name: WPShout Show Authorship this Month * Description: Show who's written what this month on WPShout * Version: 1.0 * Author: WPShout * Author URI: https://wpshout.com */ add_shortcode( 'wpshout_show_this_months_posts_by_author', 'wpshout_show_this_months_posts_by_author' ); function wpshout_show_this_months_posts_by_author() { if( ! current_user_can( 'administrator' ) ) : return; endif; $args = array( 'posts_per_page' => -1, 'post_type' => 'any', 'post_status' => 'publish', 'date_query' => array( 'after' => array( 'year' => date( 'Y' ), 'month' => date( 'm' ), 'day' => 1, ), ), 'orderby' => 'date', 'order' => 'DESC', ); $query = new WP_Query( $args ); ob_start(); while( $query->have_posts() ) : $query->the_post(); ?> <h2><?php the_title(); ?></h2> By <?php the_author(); ?> on <?php echo get_the_date( 'l, F d, Y' ); ?> <?php endwhile; wp_reset_postdata(); return ob_get_clean(); }
Примечания к шагу 9
Оказалось, что функция the_date() выводит только один пост за одну дату. Если существуют две записи с одинаковой датой публикации, она перестает работать.
Также мне удалось выяснить, что у get_the_date() этой проблемы нет. Поэтому используем данную функцию. Результат запуск обновленного кода:
И это именно то, что нужно.
Общие мысли о разработке плагинов WordPress
Разработка плагина для WordPress – это обучение, эксперименты, исследования с помощью метода проб и ошибок. Но главное использовать имеющиеся знания для выполнения простых задач и получать новые для выполнения более сложных.