Организация типов, представлений и подписчиков WordPress
Одна из вещей, которую я пытаюсь делать на регулярной основе, — это оптимизировать то, как я создаю функциональность, ориентированную на WordPress. Я недавно говорил об этом, но подумал, что хотел бы расширить его немного больше.
То есть я решил изложить подход, который я использую при создании таких вещей, как настраиваемые типы сообщений, таксономии, мета-боксы и так далее.
В общем, думайте об этом как о стратегии, которой я следую для создания аспектов проекта, который напрямую взаимодействует с WordPress, но может потребовать несколько компонентов, таких как:
- классы, которые регистрируются в WordPress через различные хуки,
- классы, которые требуют вызовов определенных API WordPress
- и классы, которые требуют пользовательского представления.
Конечно, не каждая вещь, которая взаимодействует с WordPress, потребует всего вышеперечисленного (например, нужно ли пользовательскому типу записи представление? Нет. Но мета-поле нужно).
Организация типов WordPress
С учетом сказанного я возьму более сложный пример, такой как метабокс, а затем разберу способ, которым, по моему мнению, это можно реализовать. Я отмечу то, что считаю необходимым, и то, что не обязательно.
И, как я уже сказал, я использую метабокс в качестве примера, потому что у меня есть предыдущая ссылка, и он требует наибольшего объема работы, тогда как что-то еще, например, пользовательская таксономия, может не требовать всех (только подмножество) частей. .
С учетом сказанного позвольте мне изложить мой подход.
Нам нужны подписчики
Я говорил об этом конкретном шаблоне достаточно, чтобы просто дать ссылку на его определение. Если вы читаете эту страницу, вы, вероятно, хорошо осведомлены о различных хуках и о том, как их использовать в WordPress.
Фото Александра Эндрюса на Unsplash
Но причина, по которой я хочу упомянуть об этом, заключается в том, что вместо того, чтобы думать о подключении функции, которая срабатывает всякий раз, когда что-то происходит, я хочу, чтобы вы подумали об объекте, который подписывается на событие, когда оно происходит.
Это означает, что нам понадобится тип класса подписчика.
Классы API WordPress
Во-вторых, нам нужны классы, отвечающие за взаимодействие напрямую с WordPress. Это классы, которые обращаются к WordPress API и регистрируют все, за что они несут ответственность.
То есть, возможно, они собираются определить пользовательский тип записи или, возможно, как уже говорилось, они собираются определить мета-поле.
Определение представлений
Наконец, важно отметить, что для некоторых пользовательских функций в области администрирования WordPress (или даже в общедоступных областях) вы можете включить представление, шаблон или частичное представление (я обычно просто называю их представлениями), которое будет работайте над представлением данных для метабокса.
Фото Сакет Гаруда на Unsplash
Иногда это будет просто информативно. Иногда для этого потребуется отправить обратно на сервер и сериализовать данные. Хотя я думаю, что разговор о последнем был бы действительно полезным, он выходит за рамки текущей темы этого поста.
Возможно в будущем посте.
Организация занятий
О чем все это говорит, как бы все это выглядело? Как минимум, мы рассматриваем:
- подписчик,
- тип WordPress,
- вид
И, самое большее, вас может заинтересовать определение интерфейсов или абстрактных классов, чтобы обеспечить соблюдение контракта между различными типами WordPress. Это также здоровый объектно-ориентированный принцип, о котором я расскажу в следующем посте.
А пока давайте поговорим о том, как настроить каждый из них.
Подписчик
Проще говоря, подписчик отвечает за прослушивание всякий раз, когда WordPress создает событие (публикует событие). И когда он замечает это, он запускает функцию, которая к нему привязана.
Обычно это определяется в шаблоне реестра. Если вы не читали этот пост, я рекомендую его, но настроить код для него довольно просто:
<?php
class AcmeMetaBoxSubscriber extends AbstractSubscriber
{
public function __construct(string $hook)
{
parent::__construct($hook);
}
public function load()
{
(new AcmeMetaBox())->render();
}
}
Оттуда всякий раз, когда возникает событие, функция будет срабатывать. Но вот в чем дело: функция должна быть частью определенного класса. Таким образом, потребность в WordPress-типе
Тип WordPress
Мне нравится рассматривать типы вещей, которые взаимодействуют с WordPress, как типы WordPress (так же, как наши языки программирования имеют собственные типы, такие как строки и целые числа). В WordPress есть таксономии, метабоксы, меню и так далее.
Для того, чтобы наш подписчик работал корректно, он должен быть осведомлен о нашем типе WordPress. В соответствии с примером метабокса, вот как это может выглядеть:
<?php
class AcmeMetaBox extends AbstractMetaBox
{
public function render()
{
add_meta_box(
'acme-data',
'Acme Data',
[$this, 'display'],
$this->postType,
'normal',
'high'
);
}
public function display()
{
include_once plugin_dir_path(__FILE__).'Views/acme-data.php';
}
}
Затем нам нужно убедиться, что реестр знает об этом классе.
Вид
Наконец, для метабокса нам нужно убедиться, что есть представление, которое, по крайней мере, будет отображать информацию. Сериализация информации и последующее обновление представления для пользователя — это немного другой зверь.
Но как может выглядеть вид? Легко :
<div class="acme-data-metabox">
<?php echo __('Acme Data', 'acme-meta-box'); ?>
<p class="description">
This is the content of the metabox.
</p>
</div>
Это просто базовая разметка, которая отображает информацию для пользователя.
Связывание всего вместе
Всякий раз, когда я собираю все это вместе, у меня обычно есть класс плагина, который запускает все это. Если проект большой, их может быть больше одного, но в этом случае я думаю, что можно показать, как это выглядит, используя один класс.
Итак, во-первых, основной класс плагина выглядит так:
<?php
class Plugin
{
private $registry;
public function __construct(Registry $registry)
{
$this->registry = $registry;
}
public function start()
{
array_map(function ($subscriber) {
add_action($subscriber->getHook(), [$subscriber, 'load']);
}, $this->registry->getRegisteredSubscribers());
}
}
И бутстрап для плагина выглядит так:
<?php
// Setup a filter so we can retrieve the registry throughout the plugin.
$registry = new Registry();
add_filter('acmeApiRegistry', function() use ($registry) {
return $registry;
});
// Register all of our objects with a basic registry.
$registry->add('acmeMetaBoxSubscriber', new AcmeMetaBoxSubscriber('add_meta_boxes'));
$plugin = new Plugin($registry);
$plugin->start();
И оттуда все остальное приводится в движение.
А как насчет расширенной функциональности?
Я поднимаю этот вопрос, потому что я уже немного говорил об этом ранее в посте. А именно я говорил о:
- идея отправки данных обратно на сервер (и, вероятно, их повторного чтения),
- и я говорил об использовании интерфейсов.
Я думаю, что обе эти вещи стоит изучить более подробно. Но прежде чем сделать это, закладываю основу того, как я организую эту информацию, особенно учитывая, что она основана на предыдущих сообщениях, таких как шаблон реестра, а также на организации классов, ориентированных на WordPress, с помощью мета-полей.
