✅ Notizie, temi, plugin WEB e WordPress. Qui condividiamo suggerimenti e le migliori soluzioni per siti web.

Widget WordPress: refactoring, parte 3

22

In termini di aggiornamento di WordPress Widget Boilerplate (che è tutto tracciato nel ramo di sviluppo ), abbiamo fatto molta strada in termini di refactoring di come è organizzato.

Widget WordPress: refactoring, parte 3

Finora abbiamo:

Ora siamo pronti per iniziare il refactoring di questo codice in un modo molto più orientato agli oggetti.

Quindi, se devi ancora recuperare il ritardo con i post precedenti (qualcuno di essi, in realtà), ti consiglio di farlo perché ci vorrà un po’ di tempo per aggiornarlo. C’è molto codice per scrivere una spiegazione.

Iniziamo.

The WordPress Widget Boilerplate: Refactoring, Parte 3

Probabilmente, il problema più grande con Boilerplate è che tutto è incapsulato all’interno di una singola classe.

Certo, ci sono alcune cose belle come mantenere le nostre opinioni separate dalla logica lato server, ma questo è il massimo.

Altri problemi che esistono solo guardando il codice includono:

  • aggiungendo azioni e filtri nel costruttore,
  • avere metodi che fanno più di una cosa,
  • non avere classi responsabili dell’implementazione di cose come la registrazione delle dipendenze,
  • e così via.

In questo post, inizieremo il processo di creazione di astrazioni che alla fine implementeremo per spezzare la natura di classe divina del Boilerplate così com’è.

Questo verrà suddiviso in diversi post in modo da poter fornire una solida spiegazione del motivo per cui stiamo facendo determinate cose che stiamo facendo, oltre a spiegare gli esempi dietro.

Se lo faccio in un altro modo, la serie tralascia troppe informazioni preziose applicabili ad altre pratiche di programmazione orientata agli oggetti.

Che cos’è un abbonato?

Il sistema di hook di WordPress, ovvero le azioni e i filtri che abbiamo a disposizione, si basano su un modello di progettazione basato sugli eventi. Ciò significa che ogni volta che succede qualcosa, un evento, WordPress attiverà qualsiasi altro codice che si è iscritto a tale evento.

Quindi, quando registriamo una funzione con un hook , ci iscriviamo all’evento. A tal fine, sono un fan della creazione di abbonati per qualsiasi hook di cui avremo bisogno.

Inoltre, gli abbonati generalmente seguono un formato coerente. Ciò significa che è davvero facile creare una classe astratta che implementi alcune delle funzionalità coerenti e quindi consenta alla classe che implementa la classe astratta di concentrarsi esclusivamente sulla logica aziendale.

Uno dei modi più semplici per dimostrarlo è attraverso l’abbonamento per i file CSS e JavaScript perché sono due delle cose più comuni che utilizziamo durante la creazione di plug-in.

Creazione di una classe astratta

Prima di implementare la classe astratta, spieghiamo esattamente cosa faremo per crearla.

  1. Abbiamo bisogno di una proprietà che rappresenti l’evento a cui ci stiamo iscrivendo.
  2. Abbiamo bisogno di una funzione da attivare ogni volta che l’hook viene attivato da WordPress. Un altro modo di pensare a questo è che abbiamo bisogno di una funzione da implementare ogni volta che una determinata azione o filtro viene attivato da WordPress.
  3. Abbiamo bisogno di classi per implementare l’astrazione.

Per prima cosa, definiamo classi astratte. Direttamente dal manuale PHP, leggiamo:

Le classi definite come astratte non possono essere istanziate e anche qualsiasi classe che contiene almeno un metodo astratto deve essere astratta. I metodi definiti come astratti dichiarano semplicemente la firma del metodo: non possono definire l’implementazione.

In breve, questo significa che non possiamo effettivamente creare un’istanza di una classe astratta. Possiamo solo istanziare classi che definiscono l’implementazione.

Widget WordPress: refactoring, parte 3

Questo non significa, però, che la classe astratta non possa implementare cose concrete (come la definizione di un hook). Ma significa che ci sono alcuni metodi che non hanno implementazione.

Altrimenti ci resta solo una lezione di base.

Ha senso? Diamo un’occhiata.

Creazione di una classe astratta

Per questo post creeremo una classe astratta specifica per i file CSS e JavaScript.

Ricorda, poiché questa è una classe astratta, gli abbonati concreti possono essere chiamati qualcosa che identifica ciò che fanno (ovvero, possono chiamare se stessi qualsiasi cosa rappresenti il ​​loro scopo). E arriveremo a questo.

Ma prima, la classe astratta. Condividerò il codice, quindi spiegherò esattamente cosa sta succedendo:

<?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. Si noti che la proprietà che abbiamo creato è protetta. Questo è così che le classi di implementazione possono accedervi, ma qualsiasi cosa al di fuori di essa non può.
  2. Ho creato una funzione per recuperare l’hook che diventerà evidente in seguito. In genere, odio implementare funzionalità che non sono immediatamente ovvie, ma questo è qualcosa di importante dato dove siamo diretti.
  3. C’è una funzione astratta chiamata load. È qui che qualsiasi classe che implementa questa funzione ospiterà la sua logica di business, come vedremo momentaneamente.
  4. Mi piace documentare lo scopo delle funzioni quando necessario in modo che siano in un unico posto e quindi lasciare che le classi di implementazione forniscano la documentazione che devono fornire nella loro implementazione. Lo vedrai momentaneamente anche tu.

Ora che abbiamo la classe astratta in atto, l’ultima cosa che dobbiamo fare è assicurarci che sia posizionata nella directory corretta e con uno spazio dei nomi. Se hai seguito a partire dal post precedente, probabilmente sei stato in grado di indovinare dove risiederà in base allo spazio dei nomi nel codice.

Widget WordPress: refactoring, parte 3

E se no, nessun problema. Capire gli spazi dei nomi e cosa no può richiedere un po’ di tempo. Quindi, attraverso questi post di iscrizione e questi esempi, spero che diventi chiaro nel tempo.

Creazione di classi concrete

Ora implementiamo questa particolare classe per aggiungere sia i fogli di stile che i sorgenti JavaScript che abbiamo. Quello che noterai, però, è che sono molto simili.

L’unica cosa che differisce è l’implementazione della funzionalità di caricamento che è esattamente come dovrebbe funzionare.

Fogli di stile

Data la classe astratta sopra, ora dobbiamo creare una classe per la registrazione dei fogli di stile. Dato che abbiamo due fogli di stile, creeremo due classi:

  1. la prima classe si occuperà della registrazione del foglio di stile per la dashboard e nello specifico per la pagina del widget di WordPress,
  2. la seconda classe sarà responsabile della registrazione del plugin per il blog vero e proprio.

Chiamiamo rispettivamente ciascuno di questi AdminStylesheetSubscriber e PublicStylesheetSubscriber.

Innanzitutto, l’abbonato al foglio di stile dell’amministratore :

<?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'
        );
    }
}

Nota che questo utilizza la funzione get_current_screen() che ho usato nei post precedenti per assicurarmi di aggiungere dipendenze solo dove necessario.

Ora, l’abbonato JavaScript pubblico. Questo utilizza la funzione is_admin() per assicurarci di non essere nell’area amministrativa di 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'
        );
    }
}

Ovviamente, dobbiamo ancora creare un’istanza di queste classi. Arriverà più avanti nella serie.

JavaScript

Gli abbonati JavaScript non sono molto diversi, come avrai intuito. Li separeremo in base all’area dell’applicazione in cui si concentrano e li denomineremo in modo appropriato.

Innanzitutto, l’abbonato JavaScript admin :

<?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'
        );
    }
}

E l’abbonato JavaScript pubblico:

<?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'
        );
    }
}

Ancora una volta, queste classi non possono ancora essere istanziate, ma ci concentreremo su questo in un prossimo post.

Astrazioni e interfacce

Ricorda che le astrazioni e le interfacce sono diverse ma sono facilmente confuse. Le interfacce contengono assolutamente zero implementazione. Al contrario, forniscono una garanzia che qualsiasi classe che implementa l’interfaccia implementerà tutti i metodi.

Le classi astratte, d’altra parte, possono avere alcune funzionalità implementate nella classe astratta lasciando il codice specifico del dominio, come il caricamento di fogli di stile e JavaScript, al metodo appropriato.

Questo diventerà evidente, se non lo è già, più ci addentreremo in questa serie. Nel frattempo, e come al solito, non dimenticare di controllare il ramo di sviluppo per vedere a che punto siamo con il codice.

Fonte di registrazione: tommcfarlin.com

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More