Как сделать плагин WordPress расширяемым
Опубликовано: 2022-03-10Вы когда-нибудь использовали плагин и хотели, чтобы он делал что-то по-другому? Возможно, вам нужно было что-то уникальное, выходящее за рамки страницы настроек плагина.
Я лично сталкивался с этим, и я уверен, что вы тоже. Если вы являетесь разработчиком плагинов для WordPress, скорее всего, некоторые из ваших пользователей также сталкивались с этим при использовании вашего плагина.
Вот типичный сценарий: вы, наконец, нашли плагин, который делает все, что вам нужно, за исключением одной крошечной важной вещи. Нет никаких настроек или опций для включения этой крошечной вещи, поэтому вы просматриваете документацию и обнаруживаете, что ничего не можете с этим поделать. Вы запрашиваете эту функцию на форуме поддержки плагина WordPress, но не играете в кости. В конце концов, вы удаляете его и продолжаете поиск.
Представьте, если бы вы были разработчиком этого плагина. Что бы вы сделали, если бы пользователь попросил какую-то конкретную функциональность?
Идеальным было бы реализовать это. Но если бы эта функция предназначалась для особого случая использования, то добавлять ее было бы нецелесообразно. Было бы нехорошо иметь настройку плагина, которую могли бы использовать только 0,1% ваших пользователей.
Вы хотели бы реализовать только функции, которые влияют на большинство ваших пользователей. На самом деле 80% пользователей используют 20% функций (правило 80/20). Итак, убедитесь, что любая новая функция пользуется большим спросом и что 80% ваших пользователей получат от нее пользу, прежде чем внедрять ее. Если вы создадите настройку для каждой запрашиваемой функции, тогда ваш плагин станет сложным и раздутым — а это никому не нужно.
Лучше всего сделать плагин расширяемым с точки зрения кода, чтобы другие люди могли улучшать или модифицировать его для своих нужд.
В этой статье вы узнаете, почему сделать ваш плагин расширяемым — хорошая идея. Я также поделюсь несколькими советами о том, как я научился это делать.
Что делает плагин расширяемым?
В двух словах, расширяемый плагин означает, что он придерживается части «O» SOLID-принципов объектно-ориентированного программирования, а именно принципа открытости/закрытости.
Если вы не знакомы с принципом открытости/закрытости, это в основном означает, что другим людям не нужно редактировать ваш код, чтобы что-то изменить .
Применяя этот принцип к плагину WordPress, это будет означать, что плагин является расширяемым, если в нем есть положения, позволяющие другим людям изменять его поведение. Это похоже на то, как WordPress позволяет людям «подключаться» к различным областям WordPress, но на уровне плагина.
Типичный пример плагина
Давайте посмотрим, как мы можем создать расширяемый плагин, начав с примера плагина, который таковым не является.
Предположим, у нас есть плагин, который генерирует виджет боковой панели, отображающий заголовки трех последних сообщений. В основе плагина лежит функция, которая просто заключает заголовки этих трех сообщений в теги списка:
function get_some_post_titles() { $args = array( 'posts_per_page' => 3, ); $posts = get_posts( $args ); $output = '
- ';
foreach ($ сообщения как $ сообщение) {
$выход .= '
- ' . $post->post_title . ' '; } $выход .= '
Хотя этот код работает и выполняет свою работу, он не является полностью расширяемым.
Почему? Поскольку функция задается по-своему, невозможно изменить ее поведение без непосредственного изменения кода.
Что, если пользователь захочет отобразить более трех сообщений или, возможно, включить ссылки с заголовками сообщений? С приведенным выше кодом это сделать невозможно. Пользователь зациклен на том, как работает плагин, и ничего не может изменить.
Включение сотни настроек — это не ответ
Существует несколько способов улучшить вышеуказанный плагин, чтобы пользователи могли его настраивать.
Одним из таких способов было бы добавить множество опций в настройки, но даже это может не удовлетворить всех возможностей, которые пользователи хотели бы получить от плагина.
Что, если пользователь захочет сделать что-либо из следующего (сценарии, которые мы рассмотрим позже):
- отображать продукты или сообщения WooCommerce из определенной категории;
- отображать элементы в карусели, предоставляемой другим плагином, а не в виде простого списка;
- выполнить пользовательский запрос к базе данных, а затем использовать сообщения этого запроса в списке.
Если бы мы добавили сотню настроек в наш виджет, то смогли бы охватить вышеперечисленные варианты использования. Но что, если один из этих сценариев изменится, и теперь пользователь захочет отображать только те продукты WooCommerce, которые в данный момент есть в наличии? Для этого виджету потребуется еще больше настроек. Довольно скоро у нас будет миллион настроек.
Кроме того, плагин с огромным списком настроек не совсем удобен для пользователя. Держитесь подальше от этого маршрута, если это возможно.
Итак, как бы мы подошли к решению этой проблемы? Мы бы сделали плагин расширяемым.
Добавление наших собственных хуков, чтобы сделать его расширяемым
Изучив код плагина выше, мы видим несколько операций, которые выполняет основная функция:
- Он получает сообщения, используя
get_posts
. - Он генерирует список заголовков сообщений.
- Он возвращает сгенерированный список.
Если бы другие люди изменили поведение этого плагина, их работа, скорее всего, включала бы эти три операции. Чтобы сделать наш плагин расширяемым, нам пришлось бы добавить вокруг них хуки, чтобы открыть их для других разработчиков.
В общем, это хорошие области для добавления хуков в плагин:
- вокруг и внутри основных процессов,
- при построении выходного HTML,
- для изменения сообщений или запросов к базе данных,
- перед возвратом значений из функции.
Типичный пример расширяемого плагина
Принимая во внимание эти эмпирические правила, мы можем добавить следующие фильтры, чтобы сделать наш плагин расширяемым:
- добавьте
myplugin_get_posts_args
для изменения аргументовget_posts
, - добавить
myplugin_get_posts
для переопределения результатовget_posts
, - добавить
myplugin_list_item
для настройки генерации записи списка, - добавьте
myplugin_get_some_post_titles
для переопределения возвращаемого сгенерированного списка.
Вот код снова со всеми добавленными хуками:
function get_some_post_titles() { $args = array( 'posts_per_page' => 3, ); // Let other people modify the arguments. $posts = get_posts( apply_filters( 'myplugin_get_posts_args', $args ) ); // Let other people modify the post array, which will be used for display. $posts = apply_filters( 'myplugin_get_posts', $posts, $args ); $output = '
- ';
foreach ($ сообщения как $ сообщение) {
// Разрешить другим людям изменять запись списка.
$выход .= '
- ' . apply_filters('myplugin_list_item', $post->post_title, $post). ' '; } $выход .= '
Вы также можете получить приведенный выше код в архиве GitHub.
Я добавляю здесь много хуков, что может показаться непрактичным, потому что код примера довольно прост и мал, но он иллюстрирует мою точку зрения: добавив всего четыре хука, другие разработчики теперь могут настраивать поведение плагина всевозможными способами.
Пространство имен и контекст для хуков
Прежде чем продолжить, обратите внимание на две важные вещи о реализованных нами хуках:
- Мы используем пространство имен хуков с помощью
myplugin_
.
Это гарантирует, что имя хука не конфликтует с хуком другого плагина. Это просто хорошая практика, потому что вызов другого хука с таким же именем может привести к нежелательным эффектам. - Мы также передаем ссылку на
$args
во все хуки для контекста.
Я делаю это для того, чтобы, если другие используют этот фильтр для изменения чего-либо в потоке кода, они могли использовать этот параметр$args
в качестве ссылки, чтобы получить представление о том, почему был вызван хук, чтобы они могли соответствующим образом выполнить свои корректировки.
Эффекты наших крючков
Помните уникальные сценарии, о которых я говорил ранее? Давайте вернемся к ним и посмотрим, как наши хуки сделали их возможными:
- Если пользователь хочет отобразить продукты или сообщения WooCommerce из определенной категории , то он может либо использовать фильтр
myplugin_get_posts_args
, чтобы добавить свои собственные аргументы, когда плагин запрашивает сообщения, либо он может использоватьmyplugin_get_posts
, чтобы полностью заменить сообщения своим собственным списком. - Если пользователь хочет отобразить элементы в карусели, предоставляемой другим плагином , а не в виде простого списка, он может переопределить весь вывод функции с помощью
myplugin_get_some_post_titles
и вместо этого вывести оттуда карусель. - Если пользователь хочет выполнить пользовательский запрос к базе данных , а затем использовать сообщения этого запроса в списке, то, как и в первом сценарии, он может использовать
myplugin_get_posts
для использования своего собственного запроса к базе данных и изменения массива сообщений.
Намного лучше!
Краткий пример использования наших фильтров
Разработчики могут использовать add_filter
для подключения к нашим фильтрам выше (или использовать add_action
для действий).
Используя наш первый сценарий выше, разработчик может просто сделать следующее, чтобы отобразить продукты WooCommerce, используя созданный нами фильтр myplugin_get_posts_args
:
add_filter( 'myplugin_get_posts_args', 'show_only_woocommerce_products' ); function show_only_woocommerce_products( $args ) { $args['post_type'] = 'product'; return $args; }
Мы также можем использовать хуки действий
Помимо использования apply_filters
, мы также можем использовать do_action
, чтобы сделать наш код расширяемым. Разница между ними заключается в том, что первый позволяет другим изменять переменную, а второй позволяет другим выполнять дополнительные функции в различных частях нашего кода.
При использовании действий мы, по сути, раскрываем поток плагина другим разработчикам и позволяем им выполнять другие действия в тандеме.
Это может быть бесполезно в нашем примере (потому что мы показываем только шорткод), но может быть полезно в других. Например, имея расширяемый плагин резервного копирования, мы могли бы создать плагин, который также загружает файл резервной копии в стороннюю службу, такую как Dropbox.
"Здорово! Но почему я должен заботиться о том, чтобы сделать мой плагин расширяемым?»
Что ж, если вы все еще не в восторге от этой идеи, вот несколько соображений о том, почему позволять другим людям изменять поведение вашего плагина — это хорошая идея.
Это открывает плагин для дополнительных возможностей настройки
У всех разные потребности. И есть большая вероятность, что ваш плагин не удовлетворит их всем, и вы не можете их предвидеть. Открытие вашего плагина для внесения изменений в ключевые области поведения вашего плагина может творить чудеса.
Это позволяет людям вносить изменения, не касаясь кода плагина.
Другие разработчики не будут вынуждены напрямую изменять файлы вашего плагина. Это огромное преимущество, потому что прямое изменение файла плагина, как правило, является плохой практикой. Если плагин обновится, все ваши модификации будут стерты.
Если мы добавим свои собственные хуки для использования другими людьми, тогда модификации плагина можно будет разместить во внешнем месте, например, в другом плагине. Таким образом, исходный плагин вообще не будет затронут, и его можно будет свободно обновлять, ничего не ломая, а все модификации в другом плагине останутся нетронутыми.
Заключение
Расширяемые плагины действительно потрясающие и дают нам много возможностей для настройки. Если вы сделаете свой плагин расширяемым, ваши пользователи и другие разработчики полюбят вас за это.
Взгляните на такие плагины, как WooCommerce, Easy Digital Downloads и ACF. Эти плагины являются расширяемыми, и вы можете легко сказать, потому что многие другие плагины в каталоге плагинов WordPress добавляют к ним функциональность. Они также предоставляют широкий спектр хуков действий и фильтров, которые изменяют различные аспекты плагинов. Эмпирические правила, которые я перечислил выше, возникли при моем их изучении.
Вот несколько советов, как сделать ваш плагин расширяемым:
- Следуйте принципу открыто/закрыто. Другие люди не должны редактировать ваш код, чтобы что-то изменить.
Чтобы сделать ваш плагин расширяемым, добавьте хуки в этих местах:
- вокруг и внутри основных процессов,
- при построении выходного HTML,
- для изменения сообщений или запросов к базе данных,
- перед возвратом значений из функции.
- Назовите имена ваших хуков именем вашего плагина, чтобы предотвратить конфликты имен.
- Попробуйте передать другие переменные, связанные с хуком, чтобы другие люди получили некоторый контекст того, что происходит в хуке.
- Не забудьте задокументировать ловушки вашего плагина, чтобы другие люди могли узнать о них.
Дальнейшее чтение
Вот несколько ресурсов, если вы хотите узнать больше о расширении плагинов:
- Как сделать ваш плагин WordPress расширяемым, GitHub
Весь пример кода в этой статье. - «Полезные советы по началу работы с хуками WordPress», Томас Майер, Smashing Magazine
- «Как создать плагин для WordPress», Даниэль Патаки, Smashing Magazine
- «Крючки», Справочник по плагинам, WordPress.org