Когда дело доходит до написания плагинов WordPress, обычно есть два способа сделать это: объектно-ориентированное программирование и функциональное программирование (с исключением виджетов — об этом мы поговорим позже в этой статье).
Хотя у вас обычно есть люди, которые отстаивают один стиль программирования по сравнению с другим, каждый из них имеет свои преимущества и недостатки.
В этой серии из двух частей мы с Стивеном Харрисом разберем два способа написания плагинов для WordPress. В частности, я собираюсь поговорить об объектно-ориентированном программировании, а он расскажет о функциональном программировании.
Поскольку уровень опыта читателей варьируется, мы будем говорить о программировании на высоком уровне, поэтому, если вы новичок, у вас не должно возникнуть никаких проблем. Однако, если вы более опытный разработчик, вы можете найти более полезную информацию позже в этой статье.
С учетом сказанного давайте начнем рассматривать объектно-ориентированный подход к разработке плагинов WordPress.
Разработка виджетов WordPress
Как упоминалось во введении, плагины могут быть разработаны для WordPress двумя способами:
- Объектно-ориентированного программирования
- Функциональное программирование
Вторая статья серии будет посвящена функциональному программированию, но давайте предоставим рабочее определение объектно-ориентированного программирования, чтобы мы все были на одном уровне на протяжении всей этой статьи.
Объектно-ориентированное программирование (ООП) — это парадигма программирования, использующая «объекты» — обычно экземпляры класса — состоящие из полей данных и методов вместе с их взаимодействиями — для разработки приложений и компьютерных программ.
Тем, кто более опытен в компьютерном программировании, особенно тем, кто использует методы объектно-ориентированного программирования, вероятно, понравится это определение.
Но давайте упростим это для целей этой статьи:
Объектно-ориентированное программирование — это метод программирования, который использует совокупность связанных методов для определения компьютерной программы или части компьютерной программы.
Достаточно просто, верно? В нашем случае наши плагины, безусловно, являются частью компьютерной программы, так как они подключаются к WordPress.
Хотя мы будем рассматривать код в оставшейся части этой статьи, обратите внимание, что объектно-ориентированные программы идентифицируются по группировке связанных с ними методов, и это делается в контексте того, что называется классом — который мы кратко рассмотрим ,
Слово о виджетах
Хотя правда, что плагины WordPress могут разрабатываться с использованием ООП или функционального программирования, есть исключение, когда речь идет о разработке виджетов.
Согласно статье Кодекса о разработке виджетов , следующая структура должна использоваться для написания виджета:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
class My_Widget extends WP_Widget {
public function __construct() {
// widget actual processes
}
public function form( $instance ) {
// outputs the options form on admin
}
public function update( $new_instance, $old_instance ) {
// processes widget options to be saved
}
public function widget( $args, $instance ) {
// outputs the content of the widget
}
}
|
Это означает, что все виджеты должны быть написаны с использованием ООП. Если вы не видели код, подобный приведенному выше, мы рассмотрим его в следующем разделе, и он должен предоставить все, что вам нужно знать, чтобы понять, что происходит.
Краткое введение в ООП
Прежде чем мы начнем рассматривать создание плагинов для WordPress на основе ООП, давайте более подробно рассмотрим основы ООП, чтобы убедиться, что мы четко разбираемся в терминологии и в том, как работает парадигма.
Классы
Как мы определили ранее, ООП использует «набор связанных методов». Но мы не можем останавливаться на достигнутом. В конце концов, функциональное программирование делает то же самое.
В ООП все эти «связанные методы» связаны в контексте того, что называется class
. В приведенном выше примере виджета вы увидите ключевое слово class
в качестве самого первого слова в коде.
Он начинается со строки, заканчивающейся открывающей скобкой (во многом как функции), а затем инкапсулирует или оборачивает все связанные с ней функции перед завершением закрывающей скобкой (пока игнорируем ключевое слово extends
в примере виджета — мы Я коснусь этого в ближайшее время).
Логическая группировка функций
Если вы только начинаете писать классы и вам интересно, принадлежит ли функция к данному классу, спросите себя, будет ли эта функция похожа на то, что будет делать конкретный класс.
Например, в приведенном выше примере с виджетом метод update
очевидно, является тем, что должен делать виджет. Но допустим, вы пишете класс, который будет отвечать за чтение сообщения в блоге в базе данных WordPress. Для этого конкретного класса имеет смысл иметь функцию read
или read_by_id
, но должна ли она иметь функцию write
? Как насчет delete
?
В зависимости от того, как вы разработали свой класс, возможно. Но если единственной целью класса является чтение данных, то, вероятно, нет.
И это ООП: он логически группирует ваши функции вместе в классе, но эта логическая группировка зависит от ответственности, которую вы возлагаете на свой класс.
Расширенные темы в ООП
ООП — это мощная парадигма, которая используется во всем приложении WordPress. ООП допускает расширенные операции, такие как наследование (которое представлено ключевым словом extends
в классе Widget), шаблоны проектирования, которые по сути являются существующими решениями общих проблем.
Эта статья не пытается углубиться в объектно-ориентированное программирование. Это просто попытка обеспечить основу, на которой мы можем исследовать два способа написания плагинов WordPress, но я упомяну их здесь, если вам интересно углубиться в объектно-ориентированное программирование.
Разработка плагинов на основе классов
Теперь, когда мы определили объектно-ориентированное программирование и исследовали его достаточно, чтобы заложить фундамент, пришло время начать говорить о компонентах разработки на основе ООП в контексте плагинов WordPress.
В оставшейся части этой статьи мы рассмотрим основы того, что требуется для написания плагинов на основе ООП, и преимущества, которые это дает.
Определение класса
Прежде чем что- то делать в объектно-ориентированной разработке, вы должны определить свой класс. Предполагая, что у вас уже есть представление о том, что собирается делать ваш класс, обычно это вопрос того, что вы хотите назвать своим классом.
По большей части, я думаю, что просмотр примера кода всегда полезен при обучении кода, поэтому мы посмотрим на шаблон WordPress Plugin Boilerplate .
Обратите внимание, что плагин Boilerplate — это проект, который я изначально создал, чтобы помочь в запуске плагинов на основе ООП. С тех пор этому способствовало множество разных людей. Я использую это в этой статье, потому что это демонстрирует тему под рукой.
Тем не менее, обратите внимание, что определение класса для плагина Boilerplate выглядит следующим образом:
1
2
3
4
5
|
class PluginName {
// More to come…
}
|
Поскольку плагин Boilerplate является отправной точкой для разработки, мы, очевидно, переименуем класс. Для этой статьи давайте назовем это DemoPlugin
.
1
2
3
4
5
|
class DemoPlugin {
// More to come…
}
|
На данный момент мы готовы начать определение функций, которые живут в классе.
Конструктор
В ООП первой функцией, которую вы, вероятно, увидите в классе, является функция с именем «конструктор», и PHP ничем не отличается.
Простое, рабочее определение конструктора таково:
Конструктор — это место, где вы инициализируете данные, которые будут использоваться во всем классе.
Как это работает, варьируется от проекта к проекту, но есть две основные вещи, которые мы можем сделать в контексте плагина WordPress:
- Настройте текстовый домен для целей локализации
- Определите наши действия и фильтры (в частности, наши действия и наши фильтры ).
В нашем DemoPlugin
мы собираемся сделать именно это. Мы установим текстовый домен demo-plugin
и зарегистрируем действия для регистрации и постановки в очередь примера таблицы стилей и примера файла JavaScript.
Для полноты в нашем примере мы также зарегистрируем ловушку для добавления некоторого текста в конец содержимого, отображаемого в сообщении.
Сначала давайте определим конструктор:
1
2
3
4
5
6
7
|
class DemoPlugin {
public function __construct() {
}
}
|
Обратите внимание, что в PHP конструктор определяется общедоступной функцией с именем construct
, которой предшествуют два подчеркивания.
Далее давайте определим наш текстовый домен:
1
2
3
4
5
6
7
8
9
|
class DemoPlugin {
public function __construct() {
load_plugin_textdomain( ‘demo-plugin’, false, dirname( plugin_basename( __FILE__ ) ) . ‘/lang’ );
}
}
|
В приведенной выше строке кода обратите внимание, что мы определили ключ для нашего текстового домена как demo-plugin
и строка ожидает найти файлы локализации в подкаталоге с именем lang
в каталоге плагина.
Поскольку локализация выходит за рамки этой статьи, я не буду вдаваться в подробности, но вы можете просмотреть исходный код для плагинов, чтобы увидеть, как это происходит.
Далее, давайте определим действия для регистрации наших таблиц стилей и JavaScript, а также фильтр, который добавит некоторый текст в конец нашего контента:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
class DemoPlugin {
public function __construct() {
load_plugin_textdomain( ‘demo-plugin’, false, dirname( plugin_basename( __FILE__ ) ) . ‘/lang’ );
add_action( ‘wp_enqueue_scripts’, array( $this, ‘register_plugin_styles’ ) );
add_action( ‘wp_enqueue_scripts’, array( $this, ‘register_plugin_scripts’ ) );
add_filter( ‘the_content’, array( $this, ‘append_post_notification’ ) );
}
}
|
Если вы не знакомы с действиями и фильтрами, обязательно прочитайте одну из моих недавних статей здесь на Wptuts +, поскольку она объясняет разницу.
Теперь, если вы знакомы с разработкой тем WordPress или функциональным программированием, то вы, вероятно, привыкли видеть что-то вроде следующего:
1
|
add_action( ‘wp_enqueue_scripts’, ‘register_plugin_styles’ );
|
Скорее, чем:
1
|
add_action( ‘wp_enqueue_scripts’, array( $this, ‘register_plugin_styles’ ) );
|
Обратите внимание, что разница в двух вызовах выше заключается во втором параметре. В частности, в нашем плагине мы передаем массив, тогда как первая строка кода просто передает строку.
Поскольку мы разрабатываем этот плагин с использованием ООП, WordPress должен знать, где вызывать метод register_plugin_styles
. Поскольку он живет в нашем классе, мы должны сказать WordPress, чтобы он вызывал метод в экземпляре нашего класса.
Есть смысл?
По сути, мы говорим WordPress: у меня есть этот метод с именем register_plugin_styles
, но вам нужно вызвать его для экземпляра этого класса (отсюда и ключевое слово this
).
Если вы новичок в WordPress, но пришли из опыта программирования, вы можете представить, что вы говорите WordPress сделать это:
1
2
|
$demo = new DemoPlugin();
$demo->register_plugin_styles();
|
В любом случае, суть в том, что если вы разрабатываете свои плагины с использованием ООП, то вы должны зарегистрировать свои хуки, используя массив с двумя индексами: первый — $this
а второй — имя функции.
Примечание о передаче по ссылке и передаче по значению
Опытные разработчики будут знакомы со способностью PHP передавать по референду и передавать по значению. В WordPress Development нередко можно увидеть следующее:
1
|
add_action( ‘wp_enqueue_scripts’, array( &$this, ‘register_plugin_styles’ ) );
|
Где this
передается по ссылке; однако, начиная с PHP 5.4, возможность передавать переменные по ссылке во время вызова была удалена. Вот почему этот учебник предпочитает передавать по значению.
функции
В программировании функции — это единицы кода, которые по существу отвечают за «выполнение чего-либо». В объектно-ориентированном программировании полезно думать о них немного по-другому.
В ООП классы обычно представлены существительными. В нашем случае у нас есть DemoPlugin
. Точно так же функции часто являются глаголами. То есть это действия, которые может предпринять наше существительное. На данный момент мы уже решили определить следующие функции:
-
register_plugin_styles
-
register_plugin_scripts
-
append_post_notification
Обратите внимание, что каждое имя функции представляет действие, которое можно выполнить. Это хорошее практическое правило при написании функций.
В функциональном программировании на самом деле есть только идея функций; однако в ООП существует несколько различных типов функций, два из которых являются «общедоступными» функциями и «частными» функциями.
Публичные функции
Публичные функции — это функции, которые доступны за пределами класса. Это означает, что вы можете вызывать эти методы после создания экземпляра класса.
Это именно то, что мы сделали ранее в следующем коде:
1
2
|
$demo = new DemoPlugin();
$demo->register_plugin_styles();
|
По сути, эти функции доступны общественности (где публика может быть программистом или другим объектом).
Функции, которые мы пишем для регистрации наших таблиц стилей, нашего JavaScript, и которые мы пишем для добавления текста в сообщение, должны быть помечены как общедоступные, поскольку к ним будет обращаться сторонний вызов — WordPress.
Давайте определим две функции для действия wp_enqueue_scripts
:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
public function register_plugin_styles() {
wp_register_style( ‘demo-plugin’, plugins_url( ‘demo-plugin/css/plugin’ ) );
wp_enqueue_style( ‘demo-plugin’ );
}
public function register_plugin_scripts() {
wp_register_script( ‘demo-plugin’, plugins_url( ‘demo-plugin/js/display.js’ ) );
wp_enqueue_script( ‘demo-plugin’ );
}
|
Еще раз отметим, что эти две функции ожидают, что таблицы стилей и JavaScript находятся в подкаталогах css и js соответственно. Чтобы увидеть это в действии, не забудьте проверить плагин Boilerplate .
Наконец, давайте определим функцию для фильтра the_content
:
1
2
3
4
5
6
7
|
public function append_post_notification( $content ) {
$notification = __( ‘This message was appended with a Demo Plugin.’, ‘demo-plugin-locale’ );
return $content .
}
|
Обратите внимание, что мы используем функцию __, чтобы убедиться, что наш скрипт локализован с textdomain
который мы определили в конструкторе.
Частные функции
Если общедоступные методы доступны любому, то это будет означать, что приватные функции не доступны никому, верно? По большей части это правильно: единственный человек, или вещь, которая может вызывать закрытые методы, это класс, в котором они определены.
Это означает, что WordPress, сторонние объекты или программисты могут программно вызывать частные функции. Закрытые функции могут быть вызваны только из класса, в котором они используются.
Вообще говоря, частные функции очень полезны при написании вспомогательных методов, то есть они полезны для внутренних манипуляций с данными, чтобы помочь другой функции выполнить свою работу.
Чтобы привести рабочий пример, давайте определим приватную функцию, которая будет возвращать локализованную строку, append_post_notification
может использовать наша функция append_post_notification
:
1
2
3
|
private function get_localized_notification() {
return __( ‘This message was appended with a Demo Plugin.’, ‘demo-plugin-locale’ );
}
|
Далее, давайте append_post_notification
рефакторинг функции append_post_notification
для вызова этого нового помощника:
1
2
3
|
public function append_post_notification( $content ) {
return $content .
}
|
Обратите внимание, что мы упростили первую функцию, добавив вторую функцию. Вы также можете утверждать, что мы повысили читабельность начальной функции, добавив вызов функции с именем, которое помогает прояснить, что происходит.
Пожалуй, самое важное, на что следует обратить внимание, это то, что для вызова приватных функций вы должны поставить перед вызовом функции ключевое слово $this
и ->
. Это говорит PHP: «Вызовите функцию get_localized_notification
которая живет в this
классе».
В любом случае, мы дали каждому методу отдельную ответственность — еще одну хорошую практику в объектно-ориентированном программировании — и продемонстрировали использование как открытых, так и частных функций.
Другие типы функций
В объектно-ориентированном программировании есть и другие типы функций, которые выходят за рамки данной статьи.
Чтобы быть полным, я хотел бы обобщить их здесь:
- Статические функции — это функции, которые не требуют вызова экземпляра класса. Вместо этого вы можете просто позвонить им напрямую по имени класса. Например:
DemoPlugin::use_this_static_method().
- Защищенные функции похожи на частные функции, за исключением подклассов. То есть единственными объектами, которые могут получить доступ к защищенным функциям, являются подклассы данного класса. Этот специфический тип функции играет на понятии наследования, которое было упомянуто ранее в статье.
Преимущества в WordPress
На данный момент мы достигли самых высоких отметок для объектно-ориентированной разработки WordPress. Подводя итог преимуществам:
1. Все функции в контексте
При использовании объектно-ориентированного программирования вам не нужно добавлять префикс функции к имени темы или имени плагина, над которым вы работаете, и вам не нужно беспокоиться о присвоении функции имени, которое может помешать ей. функция WordPress, функция другой темы или функция другого плагина.
Вместо этого все функции живут в контексте другого класса. Единственное, в чем нужно убедиться, это то, что ваш класс не назван так, чтобы он взаимодействовал с другим существующим классом.
2. Называя их вне API
Используя объектно-ориентированное программирование, вы можете программно вызывать свой плагин вне стандартного API WordPress.
Допустим, вы разрабатываете тему и хотите, чтобы что-то отображалось на боковой панели, которую предоставляет ваш плагин. В шаблоне боковой панели вы можете на самом деле создать экземпляр своего плагина, а затем вызвать методы для него, чтобы он записал информацию в боковую панель.
Это особенно полезно, когда вы работаете с шаблоном и хотите предоставить некоторые данные по умолчанию, если пользователь не вводит что-либо вручную.
Вывод
Как мы уже говорили в начале статьи: это всего лишь один из способов, которыми вы можете разрабатывать свои плагины для WordPress. Статья Стивена расскажет, как это сделать с помощью функционального программирования.
После прочтения этой статьи вы должны лучше понять объектно-ориентированное программирование, его преимущества и уметь следовать коду, документированному в Widget API, в моей связанной с Widget Boilerplate и даже во всех местах в базе кода WordPress. ,