Статьи

Два способа разработки плагинов для WordPress: объектно-ориентированное программирование

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

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

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

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

С учетом сказанного давайте начнем рассматривать объектно-ориентированный подход к разработке плагинов WordPress.


Как упоминалось во введении, плагины могут быть разработаны для WordPress двумя способами:

  1. Объектно-ориентированного программирования
  2. Функциональное программирование

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

Википедия утверждает :

Объектно-ориентированное программирование (ООП) — это парадигма программирования, использующая «объекты» — обычно экземпляры класса — состоящие из полей данных и методов вместе с их взаимодействиями — для разработки приложений и компьютерных программ.

Тем, кто более опытен в компьютерном программировании, особенно тем, кто использует методы объектно-ориентированного программирования, вероятно, понравится это определение.

Но давайте упростим это для целей этой статьи:

Объектно-ориентированное программирование — это метод программирования, который использует совокупность связанных методов для определения компьютерной программы или части компьютерной программы.

Достаточно просто, верно? В нашем случае наши плагины, безусловно, являются частью компьютерной программы, так как они подключаются к 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:

  1. Настройте текстовый домен для целей локализации
  2. Определите наши действия и фильтры (в частности, наши действия и наши фильтры ).

В нашем 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, функция другой темы или функция другого плагина.

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

Используя объектно-ориентированное программирование, вы можете программно вызывать свой плагин вне стандартного API WordPress.

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

Это особенно полезно, когда вы работаете с шаблоном и хотите предоставить некоторые данные по умолчанию, если пользователь не вводит что-либо вручную.


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

После прочтения этой статьи вы должны лучше понять объектно-ориентированное программирование, его преимущества и уметь следовать коду, документированному в Widget API, в моей связанной с Widget Boilerplate и даже во всех местах в базе кода WordPress. ,