WordPress-widgetit: Refaktorointi, osa 3
WordPress Widget Boilerplaten (joita kaikkia seurataan kehityshaarassa) päivittämisessä olemme päässeet pitkälle sen järjestelyn uudistamisessa.
Tähän mennessä olemme:
- katsoi, kuinka WordPress Widget API tarjoaa esimerkin olio-ohjelmoinnista,
- kuinka voimme käyttää tätä API :ta määrittämään olio-ohjelmointia muilla WordPressin alueilla,
- asennetut työkalut, jotka auttavat meitä arvioimaan koodin laatua,
- havaitsi virheitä, joita koodissa on tällä hetkellä nykyaikaisten ohjelmointistandardien mukaan,
- ja aloitti koodikannan uudelleenjärjestelyn, jotta se sopisi nykyaikaisempien käytäntöjen kanssa .
Nyt olemme valmiita aloittamaan tämän koodin uudelleenmuodostamisen paljon oliokeskeisemmällä tavalla.
Joten jos et ole vielä perehtynyt aikaisempiin viesteihin (todella kaikkiin niistä), suosittelen tekemään niin, koska tämän päivittäminen kestää hetken. On paljon koodia selityksen kirjoittamiseen.
Aloitetaan.
WordPress Widget Boilerplate: Refactoring, osa 3
Luultavasti Boilerplaten suurin ongelma on, että kaikki on kapseloitu yhteen luokkaan.
Toki, on joitain mukavia asioita, kuten pitää näkemyksemme erillään palvelinpuolen logiikasta, mutta se on noin pitkälle menevä.
Muita ongelmia, joita ilmenee vain koodin katsomisesta, ovat:
- lisäämällä toimintoja ja suodattimia rakentajaan,
- jolla on menetelmiä useamman kuin yhden asian tekemiseen,
- joilla ei ole luokkia, jotka ovat vastuussa asioiden, kuten riippuvuuksien rekisteröinnin, toteuttamisesta,
- ja niin edelleen.
Tässä viestissä aiomme aloittaa prosessin luoda abstraktioita, joita otamme lopulta käyttöön hajottaaksemme Boilerplaten jumalallisen luonteen sellaisenaan.
Tämä jaetaan useisiin viesteihin, jotta voin antaa vankan selityksen sille, miksi teemme tiettyjä asioita, joita teemme, sekä selittää esimerkkejä niiden takana.
Jos teen sen jollain muulla tavalla, sarja jättää liian paljon arvokasta tietoa, jota voidaan soveltaa muihin olio-ohjelmointikäytäntöihin.
Mikä on tilaaja?
WordPress hook -järjestelmä – eli käytössämme olevat toiminnot ja suodattimet – perustuvat tapahtumalähtöiseen suunnittelumalliin. Tämä tarkoittaa, että aina kun jotain tapahtuu, tapahtuma, WordPress käynnistää minkä tahansa muun koodin, joka on tilannut mainitun tapahtuman.
Joten kun rekisteröimme toiminnon koukulla, tilaamme tapahtuman. Tätä tarkoitusta varten pidän tilaajien luomisesta mille tahansa tarvitsemamme koukkuun.
Tämän lisäksi tilaajat noudattavat yleensä yhtenäistä muotoa. Tämä tarkoittaa, että on todella helppoa luoda abstrakti luokka, joka toteuttaa osan johdonmukaisista toiminnoista ja antaa sitten abstraktin luokan toteuttavan luokan keskittyä yksinomaan liiketoimintalogiikkaan.
Yksi helpoimmista tavoista osoittaa tämä on CSS-tiedostojen ja JavaScript-tiedostojen tilaaja, koska ne ovat kaksi yleisintä asiaa, joita käytämme lisäosien rakentamisessa.
Abstraktiluokan luominen
Ennen kuin otamme käyttöön abstraktin luokan, kerrotaan tarkalleen, mitä aiomme tehdä luodaksemme tämän.
- Tarvitsemme sivuston, joka edustaa tilaamaamme tapahtumaa.
- Tarvitsemme toiminnon, joka laukeaa aina, kun WordPress laukaisee koukun. Toinen tapa ajatella tätä on, että tarvitsemme toiminnon, joka toteutetaan aina, kun WordPress käynnistää tietyn toiminnon tai suodattimen.
- Tarvitsemme luokkia abstraktion toteuttamiseksi.
Ensin määritellään abstraktit luokat. Suoraan PHP-oppaasta luemme:
Abstrakteiksi määriteltyjä luokkia ei saa ilmentää, ja jokaisen luokan, joka sisältää vähintään yhden abstraktin menetelmän, on myös oltava abstrakti. Abstrakteiksi määritellyt menetelmät yksinkertaisesti ilmoittavat menetelmän allekirjoituksen – ne eivät voi määritellä toteutusta.
Lyhyesti sanottuna tämä tarkoittaa, että emme voi itse asiassa luoda abstraktin luokan esiintymää. Voimme ilmentää vain luokkia, jotka määrittelevät toteutuksen.
Tämä ei kuitenkaan tarkoita, etteikö abstrakti luokka voisi toteuttaa konkreettisia asioita (kuten koukun määritelmää). Mutta se tarkoittaa, että on tiettyjä menetelmiä, joilla ei ole toteutusta.
Muuten jäämme vain perusluokkaan.
Käydä järkeen? Katsotaanpa.
Abstraktiluokan luominen
Tätä viestiä varten aiomme luoda abstraktin luokan erityisesti CSS-tiedostoille ja JavaScriptille.
Muista, koska tämä on abstrakti luokka, konkreettisia tilaajia voidaan kutsua joksikin, joka tunnistaa heidän tekemisensä (eli he voivat kutsua itseään mille tahansa, mikä edustaa heidän tarkoitustaan). Ja siihen päästään.
Mutta ensin abstrakti luokka. Jaan koodin ja selitän tarkalleen, mitä sille tapahtuu:
<?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();
}
- Huomaa, että luomamme omaisuus on suojattu. Tämä on niin, että toteuttavat luokat voivat käyttää sitä, mutta mikään sen ulkopuolella ei voi.
- Olen luonut toiminnon koukun hakemiseen, joka tulee ilmi myöhemmin. Tyypillisesti vihaan sellaisten toimintojen käyttöönottoa, jotka eivät ole heti ilmeisiä, mutta tämä on tärkeä asia, kun otetaan huomioon, mihin olemme menossa.
- On abstrakti funktio nimeltä load. Tässä on jokainen luokka, joka toteuttaa tämän toiminnon, sisältää liiketoimintalogiikkansa, kuten näemme hetken kuluttua.
- Haluan dokumentoida funktioiden tarkoituksen tarvittaessa niin, että ne ovat yhdessä paikassa ja sitten annan toteutusluokkien toimittaa dokumentaation, jonka ne tarvitsevat toteutuksessaan. Näet tämänkin hetken.
Nyt kun meillä on abstrakti luokka paikallaan, viimeinen asia, joka meidän on tehtävä, on varmistaa, että se on sijoitettu oikeaan hakemistoon ja nimiavaruuteen. Jos olet seurannut edellisestä viestistä alkaen, olet todennäköisesti voinut arvata, missä se tulee olemaan koodin nimitilan perusteella.
Ja jos ei, ei hätää. Nimiavaruuksien ja muiden asioiden selvittäminen voi viedä vähän aikaa. Joten näiden jäsenviestien ja näiden esimerkkien kautta toivon, että se tulee selväksi ajan myötä.
Konkreettisten luokkien luominen
Toteutetaan nyt tämä tietty luokka lisätäksemme sekä tyylisivut että JavaScript-lähteet. Huomaat kuitenkin, että ne ovat hyvin samankaltaisia.
Ainoa asia, joka eroaa, on lataustoiminnon toteutus, jonka pitäisi toimia juuri näin.
Tyylitaulukot
Kun otetaan huomioon yllä oleva abstrakti luokka, meidän on nyt luotava luokka tyylitaulukoiden rekisteröintiä varten. Koska meillä on kaksi tyylitaulukkoa, luomme kaksi luokkaa:
- ensimmäinen luokka vastaa tyylitaulukon rekisteröinnistä kojelautaan ja erityisesti WordPress-widgetin sivulle,
- toinen luokka on vastuussa laajennuksen rekisteröimisestä varsinaiseen blogiin.
Kutsutaan kutakin näistä AdminStylesheetSubscriber ja PublicStylesheetSubscriber.
Ensinnäkin järjestelmänvalvojan tyylitaulukon tilaaja :
<?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'
);
}
}
Huomaa, että tämä käyttää get_current_screen()- funktiota, jota olen käyttänyt aiemmissa viesteissä varmistaakseen, että lisäämme riippuvuuksia vain tarvittaessa.
Nyt julkinen JavaScript-tilaaja. Tämä käyttää is_admin() -funktiota varmistaakseen, että emme ole WordPressin hallintoalueella.
<?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'
);
}
}
On selvää, että emme ole vielä luoneet näitä luokkia. Se tulee myöhemmin sarjassa.
JavaScript
JavaScript-tilaajat eivät ole paljon erilaisia, kuten olet ehkä arvannut. Erottelemme ne sovelluksen alueen perusteella, johon ne keskittyvät, ja nimeämme ne asianmukaisesti.
Ensinnäkin järjestelmänvalvojan JavaScript-tilaaja :
<?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'
);
}
}
Ja julkinen JavaScript-tilaaja:
<?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'
);
}
}
Jälleen kerran, näitä luokkia ei voida vielä instantoida, mutta keskitymme siihen tulevassa postauksessa.
Abstraktiot ja rajapinnat
Muista, että abstraktiot ja käyttöliittymät ovat erilaisia, mutta ne sekoittuvat helposti. Liitännät eivät sisällä lainkaan toteutusta. Sen sijaan ne takaavat, että mikä tahansa luokka, joka toteuttaa rajapinnan, toteuttaa kaikki menetelmät.
Abstrakteilla luokilla sen sijaan voidaan toteuttaa joitain toimintoja abstraktissa luokassa jättäen toimialuekohtaisen koodin – kuten tyylisivujen ja JavaScriptin lataamisen – sopivalle menetelmälle.
Tämä tulee ilmeiseksi, jos se ei ole jo käynyt ilmi, mitä pidemmälle pääsemme tähän sarjaan. Sillä välin – ja tuttuun tapaan – älä unohda tarkistaa kehityshaaraa nähdäksesi missä olemme koodin kanssa.


