{"id":230975,"date":"2022-12-06T13:01:00","date_gmt":"2022-12-06T10:01:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230975"},"modified":"2022-11-10T01:17:51","modified_gmt":"2022-11-09T22:17:51","slug":"una-guida-semplice-per-organizzare-classi-incentrate-su-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/it\/una-guida-semplice-per-organizzare-classi-incentrate-su-wordpress\/","title":{"rendered":"Una guida semplice per organizzare classi incentrate su WordPress"},"content":{"rendered":"\n<p>Una delle cose su cui ho fatto uno sforzo molto pi\u00f9 concertato, probabilmente pi\u00f9 di quanto abbia mai fatto prima, \u00e8 la gestione della separazione delle preoccupazioni tra le classi responsabili dell&#8217;interfacciamento con WordPress e quelle responsabili del lavoro con il dominio problematico.<\/p>\n<p>Ad esempio, supponiamo che stai lavorando su un plug-in e comunicher\u00e0 con un&#8217;API di terze parti. Inoltre, questo plugin offrir\u00e0 anche menu, tipi di post, tassonomie e cos\u00ec via nell&#8217;area di amministrazione di WordPress.<\/p>\n<p>Ci sono due aree di responsabilit\u00e0 qui:<\/p>\n<ol>\n<li>l&#8217;area responsabile della soluzione generale del problema,<\/li>\n<li>l&#8217;area preposta all&#8217;interfacciamento con WordPress.<\/li>\n<\/ol>\n<p>Puoi sostenere che \u00e8 importante unit\u00e0 di test delle aree che comunicano con WordPress, ma so anche che queste sono API collaudate e vere che hanno il loro set di test.<\/p>\n<p>Invece, dovremmo concentrarci sugli unit test e separare la nostra logica aziendale da WordPress.<\/p>\n<p>Ma non \u00e8 questo il punto di questo post. Invece, si tratta pi\u00f9 di un modo per presentare potenzialmente un progetto quando una parte di esso si interfaccer\u00e0 con WordPress.<\/p>\n<p>Ho parlato dell&#8217;importanza e dei vantaggi degli spazi dei nomi nei post precedenti in modo da non immergermi troppo in questa discussione qui.<\/p>\n<p>Invece, mi interessa parlare dell&#8217;organizzazione dei file a livello di filesystem e di namespace, in modo che siano nettamente separati nelle loro aree di specializzazione e cos\u00ec possiamo assicurarci di concentrare, diciamo, i nostri unit test (e altri test) sulle aree pi\u00f9 critiche.<\/p>\n<h3>Astrazione di Meta Box<\/h3>\n<p>Mi piace assicurarmi che la mia directory e la struttura dei file rispecchino quella dei miei spazi dei nomi. Certo, aiuta con l&#8217;organizzazione dei file, ma anche con un&#8217;organizzazione concettuale.<\/p>\n<p>Cio\u00e8, se lavorer\u00f2 con meta box, so che probabilmente posso trovare i file meta box in una directory annidata con la directory principale di <strong>WordPress<\/strong>, quindi all&#8217;interno di una sottodirectory <strong>Admin<\/strong> seguita da una directory <strong>MetaBox<\/strong>.<\/p>\n<p>A tal fine, come potrebbe essere un insieme di classi progettate per lavorare con i meta box, dovremmo scrivere il codice per loro in modo riutilizzabile? Dato quello che sappiamo sui meta box, sappiamo che probabilmente avremo bisogno di quanto segue:<\/p>\n<ul>\n<li>una classe astratta che definisce il tipo di post a cui sar\u00e0 legato ogni meta box,<\/li>\n<li>due funzioni per il meta box: uno per registrarlo, uno per visualizzare il contenuto,<\/li>\n<li>una directory per contenere la vista o la presentazione del meta box,<\/li>\n<li>un file che funger\u00e0 da detta vista.<\/li>\n<\/ul>\n<p>Dati i punti precedenti, forse la struttura della directory sarebbe simile a questa:<\/p>\n<\/p>\n<p>Successivamente, abbiamo un codice che rispecchia questa struttura. Cio\u00e8, all&#8217;interno della nostra directory di <strong>WordPress<\/strong>, avremmo la sottodirectory <strong>Admin<\/strong> poich\u00e9 la meta box viene visualizzata nell&#8217;area di amministrazione di WordPress e avremmo la sottodirectory <strong>View<\/strong> che conterrebbe il file responsabile della visualizzazione delle informazioni.<\/p>\n<p>Questo ci lascia con la necessit\u00e0 di creare alcune classi come elencato sopra. Forse la classe base astratta sarebbe <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2fd7f50706c3f1767dc8b5c2b7deefff#file-00-abstract-metabox-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">simile a questa:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nnamespace AcmeWordPressAdminMetaBox;\n\nabstract class AbstractMetaBox\n{\n    protected $postType;\n\n    public function __construct()\n    {\n        $this-&gt;postType = 'acme_post_type';\n    }\n\n    abstract public function render();\n    abstract public function display();\n}\n<\/code><\/pre>\n<p>Quindi un&#8217;implementazione concreta estenderebbe la classe e <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2fd7f50706c3f1767dc8b5c2b7deefff#file-01-acme-meta-box-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">assomiglierebbe a questa:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nnamespace AcmeWordPressAdminMetaBox;\n\nclass AcmeMetaBox extends AbstractMetaBox\n{\n    \/**\n     * {@inheritdoc}\n     *\/\n    public function render()\n    {\n        add_meta_box(\n            'acme-product-image',\n            'Product Image',\n            [$this, 'display'],\n            $this-&gt;postType,\n            'side',\n            'default'\n        );\n    }\n\n    \/**\n     * {@inheritdoc}\n     *\/\n    public function display()\n    {\n        include_once plugin_dir_path(__FILE__).'Views\/acme-product-image.php';\n    }\n}\n<\/code><\/pre>\n<p>E infine, la vista per la classe conterrebbe qualsiasi codice di markup e modello <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2fd7f50706c3f1767dc8b5c2b7deefff#file-02-acme-product-image-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">per il rendering delle informazioni<\/a><\/strong> :<\/p>\n<pre><code>&lt;div class=\"product-image-metabox\"&gt;\n    &lt;p&gt;\n        &lt;img src=\"&lt;?= esc_html(get_post_meta(get_the_ID(), 'product_image', true)); ?&gt;\" alt=\"&lt;?= esc_attr(get_the_title()); ?&gt;\" \/&gt;\n        &lt;input type=\"text\" value=\"&lt;?= esc_html(get_post_meta(get_the_ID(), 'product_image', true)); ?&gt;\" \/&gt;\n    &lt;\/p&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<p>Questo ci d\u00e0 esattamente ci\u00f2 di cui abbiamo bisogno in un modo ben organizzato e riutilizzabile per lavorare con i meta box. Pu\u00f2 anche essere ripetuto per cose come menu, tipi di post, tassonomie e cos\u00ec via.<\/p>\n<p>Ma sto divagando.<\/p>\n<h3>Una parola sui test unitari (con PHPUnit)<\/h3>\n<p>Come accennato in precedenza nel post, credo che le classi di unit test che risolvono problemi unici nel nostro spazio problematico siano importanti. Ci\u00f2 significa che dovresti dire al tuo file di configurazione PHPUnit di escludere i tuoi file incentrati su WordPress.<\/p>\n<p>Il vantaggio di ci\u00f2 che ho esposto sopra \u00e8 che questo diventa banalmente facile. In poche parole, puoi <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2fd7f50706c3f1767dc8b5c2b7deefff#file-03-phpunit-xml\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">aggiungerlo<\/a><\/strong> al tuo file <strong>phpunit.xml<\/strong> :<\/p>\n<pre><code>&lt;testsuites&gt;\n  &lt;testsuite name=\"Plugin\"&gt;\n    &lt;directory&gt;.\/tests&lt;\/directory&gt;\n    &lt;exclude&gt;.\/tests\/phpunit&lt;\/exclude&gt;\n    &lt;exclude&gt;.\/src\/WordPress&lt;\/exclude&gt;\n  &lt;\/testsuite&gt;\n&lt;\/testsuites&gt;<\/code><\/pre>\n<p>Ci\u00f2 ti d\u00e0 la possibilit\u00e0 di concentrarti sulla scrittura di test specifici per il tuo spazio problematico assicurandoti allo stesso tempo di scrivere codice basato su WordPress scalabile, manutenibile e riutilizzabile.<\/p>\n<p>Attualmente sto scrivendo un eBook (insieme a una variet\u00e0 di altri contenuti premium). Se sei interessato, <a href=\"https:\/\/tommcfarlin.com\/registration-info\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">controlla cosa ottieni<\/a>.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte di registrazione:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>L&#8217;organizzazione del codice per le classi incentrate su WordPress ci aiuta a concentrarci maggiormente sul nostro dominio sia in termini di risoluzione del problema che in termini di scrittura di unit test.<\/p>\n","protected":false},"author":1,"featured_media":236089,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[720],"tags":[1168],"class_list":["post-230975","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-sviluppatore","tag-affiai-it"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/230975","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/comments?post=230975"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/230975\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media\/236089"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media?parent=230975"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/categories?post=230975"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/tags?post=230975"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}