✅ WEB і WordPress новини, теми, плагіни. Тут ми ділимося порадами і кращими рішеннями для сайтів.

Віджети WordPress: рефакторинг, частина 3

19

Що стосується оновлення WordPress Widget Boilerplate (усе це відстежується у відділі розробки ), ми пройшли довгий шлях у плані рефакторингу його організації.

Віджети WordPress: рефакторинг, частина 3

Наразі ми:

Тепер ми готові розпочати рефакторинг цього коду в більш об’єктно-орієнтований спосіб.

Отже, якщо ви ще не наздогнали попередні публікації (насправді будь-яку з них), я рекомендую це зробити, оскільки це займе трохи часу, щоб оновити їх. Існує багато коду, щоб написати пояснення.

Давайте розпочнемо.

Шаблон віджета WordPress: рефакторинг, частина 3

Можливо, найбільша проблема з Boilerplate полягає в тому, що все інкапсульовано в одному класі.

Звичайно, є деякі приємні речі, як-от відокремлення наших поглядів від логіки на стороні сервера, але це все.

Інші проблеми, які виникають лише при перегляді коду, включають:

  • додавання дій і фільтрів у конструкторі,
  • маючи методи, які роблять більше ніж одну справу,
  • відсутність класів, відповідальних за реалізацію таких речей, як реєстрація залежностей,
  • і так далі.

У цьому дописі ми збираємося розпочати процес створення абстракцій, які згодом запровадимо, щоб зруйнувати природу Boilerplate, подібну до класу богів, як вона є.

Це буде розбито на кілька публікацій, щоб я міг надати чітке пояснення того, чому ми робимо певні речі, які ми робимо, а також пояснити приклади, що стоять за цим.

Якщо я зроблю це іншим способом, серія пропускає занадто багато цінної інформації, яка застосовна до інших методів об’єктно-орієнтованого програмування.

Що таке підписник?

Система підключення WordPress, тобто наявні у нас дії та фільтри, базується на керованому подіями шаблоні проектування. Це означає, що щоразу, коли щось станеться, подія, то WordPress запускатиме будь-який інший код, який підписався на цю подію.

Отже, коли ми реєструємо функцію за допомогою хука, ми підписуємося на подію. Тому я прихильник створення передплатників для будь-якого гака, який нам знадобиться.

Крім того, передплатники зазвичай дотримуються узгодженого формату. Це означає, що дуже легко створити абстрактний клас, який реалізує деякі узгоджені функції, а потім дозволяє класу, що реалізує абстрактний клас, зосередитися виключно на бізнес-логіці.

Одним із найпростіших способів продемонструвати це є підписка на файли CSS і файли JavaScript, оскільки вони є двома найпоширенішими речами, які ми використовуємо під час створення плагінів.

Створення абстрактного класу

Перш ніж реалізувати абстрактний клас, давайте чітко викладемо, що саме ми збираємося зробити, щоб його створити.

  1. Нам потрібна властивість, яка представляє подію, на яку ми підписуємося.
  2. Нам потрібна функція, яка запускатиметься щоразу, коли WordPress запускає хук. Інший спосіб думати про це: нам потрібна функція, яка буде реалізована щоразу, коли певна дія чи фільтр запускаються WordPress.
  3. Нам потрібні класи для реалізації абстракції.

Спочатку давайте визначимо абстрактні класи. Прямо з посібника PHP ми читаємо:

Класи, визначені як абстрактні, не можуть бути створені, і будь-який клас, який містить принаймні один абстрактний метод, також повинен бути абстрактним. Методи, визначені як абстрактні, просто оголошують сигнатуру методу – вони не можуть визначити реалізацію.

Коротше кажучи, це означає, що ми не можемо створити екземпляр абстрактного класу. Ми можемо створювати лише екземпляри класів, які визначають реалізацію.

Віджети WordPress: рефакторинг, частина 3

Однак це не означає, що абстрактний клас не може реалізувати конкретні речі (наприклад, визначення хука). Але це означає, що є певні методи, які не мають реалізації.

Інакше ми залишимося лише з базовим класом.

Мати сенс? Давайте поглянемо.

Створення абстрактного класу

Для цієї публікації ми створимо абстрактний клас спеціально для файлів CSS і JavaScript.

Пам’ятайте, оскільки це абстрактний клас, конкретних передплатників можна назвати якось, що ідентифікує те, що вони роблять (тобто вони можуть називати себе як завгодно, що представляє їх мету). І ми дійдемо до цього.

Але спочатку абстрактний клас. Я поділюся кодом, а потім поясню, що саме з ним відбувається:

<?php

/*
 * This file is part of the WordPress Widget Boilerplate
 *
 * (c) Tom McFarlin <tom@tommcfarlin.com>
 *
 * This source file is subject to the GPL license that is bundled
 * with this source code in the file LICENSE.
 */

namespace WordPressWidgetBoilerplateSubscriber;

/**
 * An abstract implementation of a subscriber that requires a hook and the ability to
 * start the class.
 */
abstract class AbstractSubscriber
{
    /**
     * @var string a reference to the hook to which the subscriber should be registered
     */
    protected $hook;

    /**
     * @param string $hook the hook to which the subscriber is registered
     */
    public function __construct(string $hook)
    {
        $this->hook = $hook;
    }

    /**
     * @return string the hook to which the subscriber is registered
     */
    public function getHook(): string
    {
        return $this->hook;
    }

    /**
     * Implements the domain logic for the concrete class implementating this subcriber.
     */
    abstract public function load();
}
  1. Зверніть увагу, що створений нами ресурс захищений. Це робиться для того, щоб класи реалізації могли отримати до нього доступ, але будь-що поза ним не може.
  2. Я створив функцію для отримання гака, яка стане очевидною пізніше. Як правило, я ненавиджу впроваджувати функції, які не відразу очевидні, але це те, що важливо, враховуючи, куди ми прямуємо.
  3. Існує абстрактна функція, яка називається load. Саме тут будь-який клас, який реалізує цю функцію, розмістить свою бізнес-логіку, як ми зараз побачимо.
  4. Мені подобається документувати призначення функцій, коли це необхідно, щоб вони були в одному місці, а потім дозволяти класам реалізації надавати документацію, яку вони потребують для своєї реалізації. Ви також побачите це мить.

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

Віджети WordPress: рефакторинг, частина 3

А якщо ні, не хвилюйтеся. З’ясування просторів імен і того, що ні, може зайняти трохи часу. Тому я сподіваюся, що через ці дописи учасників і ці приклади з часом це стане зрозумілим.

Створення конкретного класу

Тепер давайте реалізуємо цей конкретний клас, щоб додати як таблиці стилів, так і джерела JavaScript, які у нас є. Однак ви помітите, що вони дуже схожі.

Єдине, що відрізняється, це реалізація функціональності завантаження, яка саме так і має працювати.

Таблиці стилів

Враховуючи наведений вище абстрактний клас, тепер нам потрібно створити клас для реєстрації таблиць стилів. Оскільки у нас є дві таблиці стилів, ми створимо два класи:

  1. перший клас відповідатиме за реєстрацію таблиці стилів для інформаційної панелі та, зокрема, для сторінки віджета WordPress,
  2. другий клас відповідатиме за реєстрацію плагіна для фактичного блогу.

Давайте назвемо кожен із цих AdminStylesheetSubscriber і PublicStylesheetSubscriber відповідно.

По- перше, підписник таблиці стилів адміністратора :

<?php

/*
 * This file is part of the WordPress Widget Boilerplate
 *
 * (c) Tom McFarlin <tom@tommcfarlin.com?
 *
 * This source file is subject to the GPL license that is bundled
 * with this source code in the file LICENSE.
 */

namespace WordPressWidgetBoilerplateSubscriber;

/**
 * The subscriber responsible for loading the stylesheet on the Widget administration page.
 */
class AdminStyleAssetSubscriber extends AbstractSubscriber
{
    /**
     * {@inheritdoc}
     */
    public function __construct(string $hook)
    {
        parent::__construct($hook);
    }

    /**
     * Adds the administrative stylesheet to the widget administration page.
     */
    public function load()
    {
        if ('widgets' !== get_current_screen()->id) {
            return;
        }

        wp_enqueue_style(
            'wordpress-widget-boilerplate',
            plugin_dir_url(dirname(__DIR__)).'assets/css/admin.css'
        );
    }
}

Зверніть увагу, що тут використовується функція get_current_screen(), яку я використовував у попередніх публікаціях, щоб переконатися, що ми додаємо залежності лише там, де це необхідно.

Тепер публічний передплатник JavaScript. Це використовує функцію is_admin(), щоб переконатися, що ми не знаходимося в адміністративній області WordPress.

<?php

/*
 * This file is part of the WordPress Widget Boilerplate
 *
 * (c) Tom McFarlin <tom@tommcfarlin.com>
 *
 * This source file is subject to the GPL license that is bundled
 * with this source code in the file LICENSE.
 */

namespace WordPressWidgetBoilerplateSubscriber;

/**
 * The subscriber responsible for loading the stylesheet on the blog.
 */
class PublicStyleAssetSubscriber extends AbstractSubscriber
{
    /**
     * {@inheritdoc}
     */
    public function __construct(string $hook)
    {
        parent::__construct($hook);
    }

    /**
     * Adds the stylesheet to the public-facing side of the site.
     */
    public function load()
    {
        if (is_admin()) {
            return;
        }

        wp_enqueue_style(
            'wordpress-widget-boilerplate',
            plugin_dir_url(dirname(__DIR__)).'assets/css/widget.css'
        );
    }
}

Очевидно, ми ще не створили екземпляри цих класів. Це буде пізніше в серії.

JavaScript

Передплатники JavaScript не сильно відрізняються, як ви, можливо, здогадалися. Ми розділимо їх залежно від області програми, на якій вони зосереджені, і дамо їм відповідні назви.

По- перше, передплатник адміністратора JavaScript :

<?php

/*
 * This file is part of the WordPress Widget Boilerplate
 *
 * (c) Tom McFarlin <tom@tommcfarlin.com>
 *
 * This source file is subject to the GPL license that is bundled
 * with this source code in the file LICENSE.
 */

namespace WordPressWidgetBoilerplateSubscriber;

/**
 * The subscriber responsible for loading the JavaScript on the Widget's adminsitration page.
 */
class AdminScriptAssetSubscriber extends AbstractSubscriber
{
    /**
     * {@inheritdoc}
     */
    public function __construct(string $hook)
    {
        parent::__construct($hook);
    }

    /**
     * Adds the administrative JavaScript to the widget administration page.
     */
    public function load()
    {
        if ('widgets' !== get_current_screen()->id) {
            return;
        }

        wp_enqueue_script(
            'wordpress-widget-boilerplate',
            plugin_dir_url(dirname(__DIR__)).'assets/js/admin.js'
        );
    }
}

І публічний передплатник JavaScript:

<?php

/*
 * This file is part of the WordPress Widget Boilerplate
 *
 * (c) Tom McFarlin <tom@tommcfarlin.com>
 *
 * This source file is subject to the GPL license that is bundled
 * with this source code in the file LICENSE.
 */

namespace WordPressWidgetBoilerplateSubscriber;

/**
 * The subscriber responsible for loading the JavaScript on the blog.
 */
class PublicScriptAssetSubscriber extends AbstractSubscriber
{
    /**
     * {@inheritdoc}
     */
    public function __construct(string $hook)
    {
        parent::__construct($hook);
    }

    /**
     * Adds the JavaScript to the public-facing side of the site.
     */
    public function load()
    {
        if (is_admin()) {
            return;
        }

        wp_enqueue_script(
            'wordpress-widget-boilerplate',
            plugin_dir_url(dirname(__DIR__)).'assets/js/widget.js'
        );
    }
}

Знову ж таки, ці класи ще не можуть бути створені, але ми зосередимося на цьому в наступній публікації.

Абстракції та інтерфейси

Пам’ятайте, що абстракції та інтерфейси відрізняються, але їх легко сплутати. Інтерфейси містять абсолютно нульову реалізацію. Натомість вони гарантують, що будь-який клас, який реалізує інтерфейс, реалізує всі методи.

З іншого боку, абстрактні класи можуть мати певну функціональність, реалізовану в абстрактному класі, залишаючи предметно-спеціальний код – наприклад, завантаження таблиць стилів і JavaScript – відповідному методу.

Це стане очевидним, якщо ще не сталося, чим далі ми будемо заглиблюватися в цю серію. Тим часом – і як завжди – не забудьте перевірити гілку розробки, щоб побачити, на якому стані код.

Джерело запису: tommcfarlin.com

Цей веб -сайт використовує файли cookie, щоб покращити ваш досвід. Ми припустимо, що з цим все гаразд, але ви можете відмовитися, якщо захочете. Прийняти Читати далі