Статьи

Анатомия плагина WordPress

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

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


Написание собственного плагина — не ракетостроение, предназначенное для самых опытных программистов. Все, что тебе нужно
это базовое понимание
язык программирования PHP и некоторая информация о том, как WordPress ожидает, что ваш плагин будет себя вести. Этот урок предоставит вам последнее.

Прежде чем мы начнем, позвольте мне представить концепцию плагина и то, что мы пытаемся достичь с его помощью.

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

Вот быстрый рисунок того, как виджет может выглядеть в действии:

Давайте начнем!

Плагины в WordPress — это файлы PHP, которые были помещены в каталог wp-content/plugins каталоге установки WordPress.

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

Давайте создадим каталог для плагина «Coming Next»:

Созданный каталог: / wp-content / plugins / coming-next

В этом новом каталоге мы создаем основной PHP-файл плагина. Давайте назовем это coming-next.php .

При поиске плагинов WordPress просматривает каждый файл в каталоге плагинов в поисках комментариев, которые идентифицируют файлы как плагины. Тот
Раздел комментариев содержит основную информацию о плагине и, как минимум, должен содержать название плагина.

Вот как будет выглядеть блок комментариев для нашего плагина «Coming Next»:

01
02
03
04
05
06
07
08
09
10
<?php
/*
Plugin Name: Coming Next
Plugin URI: http://nettuts.com
Description: Shows the next scheduled posts with brief descriptions.
Version: 1.0
Author: Jarkko Laine
Author URI: http://jarkkolaine.com
*/
?>

Сохраните файл и перейдите на страницу плагинов в вашей административной области WordPress. Плагин, со всей информацией, добавленной в комментарии,
уже виден в списке плагинов:

Вот так плагин появляется в списке плагинов

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

В своей простейшей форме плагин WordPress — это не более чем одна или несколько функций, помещаемых в файл плагина.

Все функции, созданные в плагинах, видны как текущей теме, так и другим активным плагинам, поэтому можно

используйте систему плагинов для расширения платформы новыми функциями, а затем просто вызывайте их прямо из вашей темы.

Давайте сделаем это сначала и создадим функцию в основе плагина «Coming Next», list_upcoming_posts() .

Прежде чем мы начнем, мы предупреждаем одним словом: все функции, добавленные в файлы плагинов, будут видны во всем
Установка WordPress, вы должны быть очень осторожны при именовании их. Если есть две функции с одинаковым именем
в двух (или более) разных плагинах они будут конфликтовать, и вещи просто не смогут работать.

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function list_upcoming_posts($num_posts = 1, $show_excerpt = false,
                             $text_format = «Coming Up on [date]») {
  $posts = get_posts(«numberposts=».$num_posts.»&order=ASC&post_status=future»);
 
  echo «<ul class=\»upcoming-posts\»>»;
  global $post;
  $old_post = $post;
 
  foreach ($posts as $post) :
    setup_postdata($post);
    $my_date = the_date(», », », FALSE);
    $coming_up_text = str_replace(«[date]», $my_date, $text_format);
  ?>
    <li class=»upcoming-post»>
      <span class=»upcoming-post-date»><?php echo $coming_up_text;
      <span class=»upcoming-post-title»><?php the_title();
      <?php if ($show_excerpt) : ?>
        <span class=»upcoming-post-description»>
          <?php the_excerpt_rss();
        
      <?php endif;
    </li>
  <?php
  endforeach;
 
  $post = $old_post;
  setup_postdata($post);
  echo «</ul>»;
}

Эта функция использует WordPress get_posts ()
функция для получения столько будущих сообщений, сколько указано в параметре $ num_posts , либо всех будущих сообщений
если $ num_posts больше, чем фактическое доступное число.

Затем он отображает список, включающий заголовки сообщений, их запланированные даты и выдержку из сообщения, если для $ show_excerpt задано значение true.

Обратите внимание, что нам нужно использовать глобальную переменную $ post для настройки данных записи (см. Строку 10) для вызовов функций, таких как
как the_title () для работы. Теперь, если шаблон блога нуждается в доступе к текущему сообщению после рендеринга плагина,
нам нужно вернуть исходный пост, как только мы закончим (см. строки 7 и 26-27). В противном случае остальная часть контента будет отображаться с использованием последнего
сообщение, которое было настроено с помощью setup_postdata () .

Поздравляем! Вы только что написали свой первый плагин для WordPress и можете проверить его, добавив этот вызов где-то в шаблоне блога:

1
2
3
4
5
<?php
if (function_exists(«list_upcoming_posts»)) {
  list_upcoming_posts();
}
?>

Создайте пост под названием «Назад в будущее» и запланируйте его появление в вашем блоге 1 января 2020 года. Вот что вы должны увидеть:

Плагин в действии. Без каких-либо стилей CSS еще.

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

Если вы еще не знакомы с концепцией виджетов WordPress ,
вот что говорит о них документация WordPress:

Виджеты WordPress позволяют легко добавлять элементы дизайна, гаджеты, контент, изображения и многое другое на боковую панель WordPress для персонализации
Ваш блог, не зная HTML, PHP или любой другой код. Многие плагины WordPress теперь поставляются с версией виджета, что позволяет легко добавлять их на боковую панель.

Если ваша тема поддерживает виджеты, вы можете перейти на вкладку «Виджеты» в разделе «Дизайн» в области администрирования WordPress и назначить виджеты различным
позиции, которые разработчик темы создал для них:

Экран настроек «Виджеты»

Чтобы наш плагин «Coming Next» работал как виджет, нам сначала нужно создать функцию для рендеринга виджета. Как мы можем использовать
Функция list_upcoming_posts (), которую мы создали ранее, эта задача будет довольно простой.

Вот код для виджета в его простейшей форме:

1
2
3
4
5
6
function widget_coming_next($args) {
  extract($args, EXTR_SKIP);
  echo $before_widget;
  list_upcoming_posts();
  echo $after_widget;
}

Все, что делает функция — это извлекает разметку HTML, которую разработчик темы настроил для отображения перед ( $ before_widget ), и
after ( $ after_widget ) каждый виджет, а затем отображает его в списке предстоящих сообщений.

Функция extract () является стандартным PHP.
Он берет поля из данного массива ( $ args ) и создает из них локальные переменные. Еще один способ
То же самое можно было бы сделать для прямой ссылки на массив, используя «before_widget» и «after_widget» в качестве индексов массива.

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

1
2
3
4
5
6
7
function widget_coming_next_init() {
  wp_register_sidebar_widget(COMING_NEXT_WIDGET_ID,
    __(‘Coming Next’), ‘widget_coming_next’);
}
 
// Register widget to WordPress
add_action(«plugins_loaded», «widget_coming_next_init»);

Функция инициализации вызывает wp_register_sidebar_widget ()
зарегистрировать виджет в WordPress. Функция нуждается в трех параметрах: уникальный идентификатор для виджета, имя, которое будет использоваться в виджетах
страница в админке и название функции, которая будет отображать виджет.

Чтобы упростить задачу, если нам когда-либо понадобится изменить уникальный идентификатор, я создал для него константу. Таким образом, когда мы используем одну и ту же константу везде,
нам нужно будет обновить его только в одном месте. Добавьте это определение константы в начале файла виджета, сразу после блока комментария, который идентифицирует плагин:

1
define(COMING_NEXT_WIDGET_ID, «widget_coming_next»);

Теперь, когда вы перейдете на страницу «Виджеты», вы увидите там новый виджет, который будет добавлен в блог. И когда вы добавляете
виджет в позицию виджета, вы увидите, что предстоящие сообщения появляются там, где вы их положили!

Виджет «Далее» теперь добавлен в список виджетов.

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

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

Вот код для сохранения и получения настроек:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
function widget_coming_next_control() {
  $options = get_option(COMING_NEXT_WIDGET_ID);
  if (!is_array($options)) {
    $options = array();
  }
 
  $widget_data = $_POST[COMING_NEXT_WIDGET_ID];
  if ($widget_data[‘submit’]) {
    $options[‘num_posts’] = $widget_data[‘num_posts’];
    $options[‘coming_up_text’] = $widget_data[‘coming_up_text’];
    $options[‘show_excerpt’] = $widget_data[‘show_excerpt’];
 
    update_option(COMING_NEXT_WIDGET_ID, $options);
  }
 
  // Render form
  $num_posts = $options[‘num_posts’];
  $coming_up_text = $options[‘coming_up_text’];
  $show_excerpt = $options[‘show_excerpt’];
   
  // The HTML form will go here
}

Сердцем этой функции являются два вызова API WordPress:
get_option () в строке 2 и
update_option () в строке 13.
update_option () может использоваться для сохранения любой переменной в базе данных WordPress в виде пары ключ-значение и get_option для
прочитай это.

Например, в приведенном выше фрагменте кода вы увидите, что в строке 13 update_option () используется для хранения массива $ options с
ключ COMING_NEXT_WIDGET_ID .

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

Функция widget_coming_next_control () вызывается как при первом показе формы настроек, так и когда пользователь нажимает кнопку «Сохранить изменения»
сохранить настройки. Чтобы определить, была ли отправлена ​​форма или нет, мы используем скрытое поле
называется COMING_NEXT_WIDGET_ID [представить] . Если скрытое поле было сохранено, мы читаем в параметрах из
сформируйте и сохраните их (строки 8-14). И в обоих случаях, независимо от того, сохранены данные или нет, форма отображается.

Говоря о формах, эта основная часть все еще отсутствует. Скопируйте форму ниже и поместите ее в конец функции, которую мы только что создали
(сразу после строки 21, перед закрывающей скобкой):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
?>
<p>
  <label for=»<?php echo COMING_NEXT_WIDGET_ID;?>-num-posts»>
    Number of posts to show:
  </label>
  <input class=»widefat»
    type=»text»
    name=»<?php echo COMING_NEXT_WIDGET_ID; ?>[num_posts]»
    id=»<?php echo COMING_NEXT_WIDGET_ID; ?>-num-posts»
    value=»<?php echo $num_posts; ?>»/>
</p>
<p>
  <label for=»<?php echo COMING_NEXT_WIDGET_ID;?>-coming-up-text»>
    «Coming Up Next» text (use the [date] tag to
    display the publish date):
  </label>
  <input class=»widefat» type=»text»
    name=»<?php echo COMING_NEXT_WIDGET_ID; ?>[coming_up_text]»
    id=»<?php echo COMING_NEXT_WIDGET_ID; ?>-coming-up-text»
    value=»<?php echo $coming_up_text; ?>»/>
</p>
<p>
  <label for=»<?php echo COMING_NEXT_WIDGET_ID;?>-show-excerpt»>
    Show excerpt:
  </label>
  <select class=»widefat»
    name=»<?php echo COMING_NEXT_WIDGET_ID; ?>[show_excerpt]»
    id=»<?php echo COMING_NEXT_WIDGET_ID;?>-show-exceprt»>
    <option value=»1″ <?php echo ($show_excerpt == «1») ?
      Yes
    </option>
    <option value=»0″ <?php echo ($show_excerpt == «1») ?
      No
    </option>
  </select>
</p>
<input type=»hidden»
  name=»<?php echo COMING_NEXT_WIDGET_ID; ?>[submit]»
  value=»1″/>
<?php

Если вы внимательно посмотрите на форму, то заметите, что в ней нет открывающих или заканчивающих тегов. Это потому, что все активные виджеты
положить в той же форме, представленной WordPress, и сохраняются в одно нажатие «Сохранить изменения». Это будет полезно, когда вы решите написать
виджет, который можно добавлять много раз, например текстовый виджет WordPress (при этом вам нужно знать о нескольких виджетах
и все их разные состояния одновременно). Но сейчас это просто означает, что вам нужно быть осторожным с тем, как вы называете поля в своей части формы.

В этом плагине я решил использовать константу COMING_NEXT_WIDGET_ID в качестве идентификатора, чтобы определить, какие поля принадлежат этому виджету.
Использование нотации widget_id [field_id] в параметрах имени наших входных тегов делает вещи
хорошо для нас, так как они разбираются в массив с field_id в качестве индекса массива.

После создания функции экрана настроек нам все еще нужно указать WordPress на ее использование. Это делается с помощью следующего хука.
Добавьте его в функцию widget_coming_next_init (), которую мы создали ранее:

1
2
wp_register_widget_control(COMING_NEXT_WIDGET_ID,
    __(‘Coming Next’), ‘widget_coming_next_control’);

Теперь, когда вы добавите или отредактируете виджет, вы увидите, что появились новые опции:

Виджет теперь имеет настройки

И последнее, но не менее важное: мы сделаем так, чтобы рендеринг виджета использовал настройки, определенные в окне настроек Это действительно довольно просто: все, что нам нужно
сделать это, чтобы прочитать настройки с помощью функции get_option () . Замените ранее созданную функцию рендеринга виджета на
эта новая версия:

01
02
03
04
05
06
07
08
09
10
11
12
13
function widget_coming_next($args) {
  extract($args, EXTR_SKIP);
  $options = get_option(COMING_NEXT_WIDGET_ID);
 
  // Query the next scheduled post
  $num_posts = $options[«num_posts»];
  $show_excerpt = $options[«show_excerpt»];
  $coming_up_text = $options[«coming_up_text»];
 
  echo $before_widget;
  list_upcoming_posts($num_posts, $show_excerpt, $coming_up_text);
  echo $after_widget;
}

Вот и все. Вы создали виджет WordPress с настройками!
Вывод все еще выглядит довольно скучно, но с небольшим касанием CSS, он оживет и будет идеально соответствовать теме вашего блога.

Виджет Coming Next живет в действии