Простий посібник з організації занять, орієнтованих на WordPress
Одна з речей, до якої я докладаю набагато більше злагоджених зусиль, ймовірно, більше, ніж будь-коли раніше, — це управління розділенням завдань між класами, відповідальними за взаємодію з WordPress, і тими, хто відповідає за роботу з проблемним доменом.
Наприклад, припустімо, що ви працюєте над плагіном і він збирається спілкуватися зі стороннім API. Крім того, цей плагін також пропонуватиме меню, типи публікацій, таксономії тощо в області адміністрування WordPress.
Тут є дві зони відповідальності:
- область, яка відповідає за загальне вирішення проблеми,
- область, що відповідає за взаємодію з WordPress.
Ви можете стверджувати, що важливо створювати зони модульного тестування, які взаємодіють із WordPress, але я також знаю, що це перевірені та справжні API, які мають власний набір тестів.
Замість цього ми повинні зосередитися на модульному тестуванні та відокремити нашу бізнес-логіку від WordPress.
Але суть цього допису не в цьому. Натомість це більше про спосіб потенційно створити проект, коли його частина буде взаємодіяти з WordPress.
Я говорив про важливість і переваги просторів імен у попередніх публікаціях, тому не буду надто глибоко занурюватися в це обговорення тут.
Натомість мені цікаво поговорити про організацію файлів на рівні файлової системи та простору імен, щоб вони були чітко розділені на сфери спеціалізації, щоб ми могли бути впевнені, що ми, скажімо, зосереджуємо наші модульні тести (та інші тестування) на найбільш критичних ділянках.
Абстрагування метабоксів
Мені подобається переконатися, що мій каталог і структура файлів відображають структуру моїх просторів імен. Звичайно, це допомагає з організацією файлів, але також з концептуальною організацією.
Тобто, якщо я збираюся працювати з метабоксами, то я знаю, що, швидше за все, зможу знайти файли метабоксів у каталозі, вкладеному в батьківський каталог WordPress, а потім у підкаталозі Admin, а потім у каталозі MetaBox.
З цією метою, як може виглядати набір класів, призначених для роботи з метаблоками, якщо ми напишемо для них код, який можна буде використовувати повторно? Враховуючи те, що ми знаємо про метабокси, ми знаємо, що нам, швидше за все, знадобиться наступне:
- абстрактний клас, який визначає тип повідомлення, до якого буде прив’язаний кожен метабокс,
- дві функції для метабокса – одна для його реєстрації, одна для відображення вмісту,
- каталог для перегляду або представлення мета-блока,
- файл, який слугуватиме згаданим видом.
Враховуючи наведені вище пункти, можливо, структура каталогу виглядатиме так:
Далі ми маємо код, який відображає цю структуру. Тобто в нашому каталозі WordPress у нас буде підкаталог Admin, оскільки метаполе відображається в області адміністрування WordPress, і у нас буде підкаталог View, який міститиме файл, відповідальний за відображення інформації.
Це залишає нам необхідність створити кілька класів, як зазначено вище. Можливо, абстрактний базовий клас виглядав би так:
<?php
namespace AcmeWordPressAdminMetaBox;
abstract class AbstractMetaBox
{
protected $postType;
public function __construct()
{
$this->postType = 'acme_post_type';
}
abstract public function render();
abstract public function display();
}
Тоді конкретна реалізація розширила б клас, і це виглядало б так:
<?php
namespace AcmeWordPressAdminMetaBox;
class AcmeMetaBox extends AbstractMetaBox
{
/**
* {@inheritdoc}
*/
public function render()
{
add_meta_box(
'acme-product-image',
'Product Image',
[$this, 'display'],
$this->postType,
'side',
'default'
);
}
/**
* {@inheritdoc}
*/
public function display()
{
include_once plugin_dir_path(__FILE__).'Views/acme-product-image.php';
}
}
І, нарешті, представлення для класу міститиме будь-яку розмітку та код шаблону для відтворення інформації :
<div class="product-image-metabox">
<p>
<img src="<?= esc_html(get_post_meta(get_the_ID(), 'product_image', true)); ?>" alt="<?= esc_attr(get_the_title()); ?>" />
<input type="text" value="<?= esc_html(get_post_meta(get_the_ID(), 'product_image', true)); ?>" />
</p>
</div>
Це дає нам саме те, що нам потрібно, у добре організованому, багаторазовому способі роботи з метабоксами. Його також можна повторити для таких речей, як меню, типи публікацій, таксономії тощо.
Але я відволікся.
Кілька слів про модульне тестування (з PHPUnit)
Як я вже згадував раніше в публікації, я вважаю, що класи модульного тестування, які вирішують проблеми, унікальні для нашого проблемного простору, є важливими. Це означає, що вам потрібно вказати файлу конфігурації PHPUnit виключати файли, орієнтовані на WordPress.
Перевагою того, що я виклав вище, є те, що це стає тривіально легко. Простіше кажучи, ви можете додати це до свого файлу phpunit.xml :
<testsuites>
<testsuite name="Plugin">
<directory>./tests</directory>
<exclude>./tests/phpunit</exclude>
<exclude>./src/WordPress</exclude>
</testsuite>
</testsuites>
Це дає вам можливість зосередитися на написанні тестів спеціально для вашої проблемної області, водночас переконавшись, що ви пишете масштабований, підтримуваний і повторно використовуваний код на основі WordPress.
Зараз я пишу електронну книгу (разом із різноманітним іншим преміум-контентом). Якщо вам цікаво, перевірте, що ви отримуєте.