{"id":231469,"date":"2022-12-17T14:46:00","date_gmt":"2022-12-17T11:46:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231469"},"modified":"2022-12-17T14:49:05","modified_gmt":"2022-12-17T11:49:05","slug":"widget-wordpress-refactoring-parte-3","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/it\/widget-wordpress-refactoring-parte-3\/","title":{"rendered":"Widget WordPress: refactoring, parte 3"},"content":{"rendered":"\n<p>In termini di aggiornamento di WordPress Widget Boilerplate (che \u00e8 tutto tracciato nel ramo di <a href=\"https:\/\/github.com\/tommcfarlin\/WordPress-Widget-Boilerplate\/tree\/develop\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">sviluppo<\/a> ), abbiamo fatto molta strada in termini di refactoring di come \u00e8 organizzato.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-161272-61e71e5eea22f.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-161272-61e71e5eea22f.png\" alt=\"Widget WordPress: refactoring, parte 3\"><\/a><\/p>\n<p>Finora abbiamo:<\/p>\n<ul>\n<li>visto come <a href=\"https:\/\/wordpress.mediadoma.com\/it\/widget-wordpress-un-approccio-orientato-agli-oggetti\/\" title=\"l&#039;API del widget di WordPress fornisce un esempio\">l&#8217;API del widget di WordPress fornisce un esempio<\/a> di programmazione orientata agli oggetti,<\/li>\n<li>come possiamo utilizzare questa API <a href=\"https:\/\/wordpress.mediadoma.com\/it\/widget-wordpress-rileva-la-programmazione-orientata-agli-oggetti\/\" title=\"per determinare la programmazione orientata agli oggetti\">per determinare la programmazione orientata agli oggetti<\/a> in altre aree di WordPress,<\/li>\n<li>strumenti installati <a href=\"https:\/\/wordpress.mediadoma.com\/it\/widget-wordpress-a-partire-dagli-standard\/\" title=\"per aiutarci a valutare la qualit\u00e0\">per aiutarci a valutare la qualit\u00e0<\/a> del codice,<\/li>\n<li><a href=\"https:\/\/wordpress.mediadoma.com\/it\/widget-wordpress-refactoring-parte-1\/\" title=\"trovato errori che attualmente esistono nel codice\">trovato errori che attualmente esistono nel codice<\/a> in termini di moderni standard di programmazione,<\/li>\n<li>e inizi\u00f2 a riorganizzare la base di codice in modo che si adattasse alle <a href=\"https:\/\/wordpress.mediadoma.com\/it\/widget-wordpress-refactoring-parte-2\/\" title=\"pratiche pi\u00f9 moderne\">pratiche pi\u00f9 moderne<\/a>.<\/li>\n<\/ul>\n<p>Ora siamo pronti per iniziare il refactoring di questo codice in un modo molto pi\u00f9 orientato agli oggetti.<\/p>\n<p>Quindi, se devi ancora recuperare il ritardo con i post precedenti (qualcuno di essi, in realt\u00e0), ti consiglio di farlo perch\u00e9 ci vorr\u00e0 un po&#8217; di tempo per aggiornarlo. C&#8217;\u00e8 molto codice per scrivere una spiegazione.<\/p>\n<p>Iniziamo.<\/p>\n<h2>The WordPress Widget Boilerplate: Refactoring, Parte 3<\/h2>\n<p>Probabilmente, il problema pi\u00f9 grande con Boilerplate \u00e8 che tutto \u00e8 incapsulato all&#8217;interno di una singola classe.<\/p>\n<p>Certo, ci sono alcune cose belle come mantenere le nostre opinioni separate dalla logica lato server, ma questo \u00e8 il massimo.<\/p>\n<p>Altri problemi che esistono solo guardando il codice includono:<\/p>\n<ul>\n<li>aggiungendo azioni e filtri nel costruttore,<\/li>\n<li>avere metodi che fanno pi\u00f9 di una cosa,<\/li>\n<li>non avere classi responsabili dell&#8217;implementazione di cose come la registrazione delle dipendenze,<\/li>\n<li>e cos\u00ec via.<\/li>\n<\/ul>\n<p>In questo post, inizieremo il processo di creazione di astrazioni che alla fine implementeremo per spezzare la natura di classe divina del Boilerplate cos\u00ec com&#8217;\u00e8.<\/p>\n<p>Questo verr\u00e0 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.<\/p>\n<p>Se lo faccio in un altro modo, la serie tralascia troppe informazioni preziose applicabili ad altre pratiche di programmazione orientata agli oggetti.<\/p>\n<h3>Che cos&#8217;\u00e8 un abbonato?<\/h3>\n<p>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\u00f2 significa che ogni volta che succede qualcosa, un evento, WordPress attiver\u00e0 qualsiasi altro codice che si \u00e8 iscritto a tale evento.<\/p>\n<p><strong>Quindi, quando registriamo una funzione con un hook ,<\/strong> ci <strong>iscriviamo<\/strong> all&#8217;evento. A tal fine, sono un fan della creazione di abbonati per qualsiasi hook di cui avremo bisogno.<\/p>\n<p>Inoltre, gli abbonati generalmente seguono un formato coerente. Ci\u00f2 significa che \u00e8 davvero facile creare una classe astratta che implementi alcune delle funzionalit\u00e0 coerenti e quindi consenta alla classe che implementa la classe astratta di concentrarsi esclusivamente sulla logica aziendale.<\/p>\n<p>Uno dei modi pi\u00f9 semplici per dimostrarlo \u00e8 attraverso l&#8217;abbonamento per i file CSS e JavaScript perch\u00e9 sono due delle cose pi\u00f9 comuni che utilizziamo durante la creazione di plug-in.<\/p>\n<h3>Creazione di una classe astratta<\/h3>\n<p>Prima di implementare la classe astratta, spieghiamo esattamente cosa faremo per crearla.<\/p>\n<ol>\n<li>Abbiamo bisogno di una propriet\u00e0 che rappresenti l&#8217;evento a cui ci stiamo iscrivendo.<\/li>\n<li>Abbiamo bisogno di una funzione da attivare ogni volta che l&#8217;hook viene attivato da WordPress. Un altro modo di pensare a questo \u00e8 che abbiamo bisogno di una funzione da implementare ogni volta che una determinata azione o filtro viene attivato da WordPress.<\/li>\n<li>Abbiamo bisogno di classi per implementare l&#8217;astrazione.<\/li>\n<\/ol>\n<p>Per prima cosa, definiamo classi astratte. <a href=\"https:\/\/secure.php.net\/manual\/en\/language.oop5.abstract.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Direttamente dal manuale PHP<\/a>, leggiamo:<\/p>\n<blockquote>\n<p>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&#8217;implementazione.<\/p>\n<\/blockquote>\n<p>In breve, questo significa che non possiamo effettivamente creare un&#8217;istanza di una classe astratta. Possiamo solo istanziare classi che definiscono l&#8217;implementazione.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-161272-61e71e62f02d2.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-161272-61e71e62f02d2.png\" alt=\"Widget WordPress: refactoring, parte 3\"><\/a><\/p>\n<p>Questo non significa, per\u00f2, 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.<\/p>\n<p>Altrimenti ci resta solo una lezione di base.<\/p>\n<p>Ha senso? Diamo un&#8217;occhiata.<\/p>\n<h3>Creazione di una classe astratta<\/h3>\n<p>Per questo post creeremo una classe astratta specifica per i file CSS e JavaScript.<\/p>\n<p>Ricorda, poich\u00e9 questa \u00e8 una classe astratta, gli abbonati concreti possono essere chiamati qualcosa che identifica ci\u00f2 che fanno (ovvero, possono chiamare se stessi qualsiasi cosa rappresenti il \u200b\u200bloro scopo). E arriveremo a questo.<\/p>\n<p>Ma prima, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9cf10f4aadbe54f2fc2e87b619a33bcc#file-00-abstract-subscriber-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">la classe astratta.<\/a> Condivider\u00f2 il codice, quindi spiegher\u00f2 esattamente cosa sta succedendo:<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of the WordPress Widget Boilerplate\n *\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com&gt;\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace WordPressWidgetBoilerplateSubscriber;\n\n\/**\n * An abstract implementation of a subscriber that requires a hook and the ability to\n * start the class.\n *\/\nabstract class AbstractSubscriber\n{\n    \/**\n     * @var string a reference to the hook to which the subscriber should be registered\n     *\/\n    protected $hook;\n\n    \/**\n     * @param string $hook the hook to which the subscriber is registered\n     *\/\n    public function __construct(string $hook)\n    {\n        $this-&gt;hook = $hook;\n    }\n\n    \/**\n     * @return string the hook to which the subscriber is registered\n     *\/\n    public function getHook(): string\n    {\n        return $this-&gt;hook;\n    }\n\n    \/**\n     * Implements the domain logic for the concrete class implementating this subcriber.\n     *\/\n    abstract public function load();\n}\n<\/code><\/pre>\n<ol>\n<li>Si noti che la propriet\u00e0 che abbiamo creato \u00e8 <strong>protetta<\/strong>. Questo \u00e8 cos\u00ec che le classi di implementazione possono accedervi, ma qualsiasi cosa al di fuori di essa non pu\u00f2.<\/li>\n<li>Ho creato una funzione per recuperare l&#8217;hook che diventer\u00e0 evidente in seguito. In genere, odio implementare funzionalit\u00e0 che non sono immediatamente ovvie, ma questo \u00e8 qualcosa di importante dato dove siamo diretti.<\/li>\n<li>C&#8217;\u00e8 una funzione astratta chiamata <strong>load<\/strong>. \u00c8 qui che qualsiasi classe che implementa questa funzione ospiter\u00e0 la sua logica di business, come vedremo momentaneamente.<\/li>\n<li>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.<\/li>\n<\/ol>\n<p>Ora che abbiamo la classe astratta in atto, l&#8217;ultima cosa che dobbiamo fare \u00e8 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\u00e0 in base allo spazio dei nomi nel codice.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-161272-61e71e66e7d4a.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-161272-61e71e66e7d4a.png\" alt=\"Widget WordPress: refactoring, parte 3\"><\/a><\/p>\n<p>E se no, nessun problema. Capire gli spazi dei nomi e cosa no pu\u00f2 richiedere un po&#8217; di tempo. Quindi, attraverso questi post di iscrizione e questi esempi, spero che diventi chiaro nel tempo.<\/p>\n<h3>Creazione di classi concrete<\/h3>\n<p>Ora implementiamo questa particolare classe per aggiungere sia i fogli di stile che i sorgenti JavaScript che abbiamo. Quello che noterai, per\u00f2, \u00e8 che sono molto simili.<\/p>\n<p>L&#8217;unica cosa che differisce \u00e8 l&#8217;implementazione della funzionalit\u00e0 di <strong>caricamento<\/strong> che \u00e8 esattamente come dovrebbe funzionare.<\/p>\n<h5>Fogli di stile<\/h5>\n<p>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:<\/p>\n<ol>\n<li>la prima classe si occuper\u00e0 della registrazione del foglio di stile per la dashboard e nello specifico per la pagina del widget di WordPress,<\/li>\n<li>la seconda classe sar\u00e0 responsabile della registrazione del plugin per il blog vero e proprio.<\/li>\n<\/ol>\n<p>Chiamiamo rispettivamente ciascuno di questi <strong>AdminStylesheetSubscriber<\/strong> e <strong>PublicStylesheetSubscriber<\/strong>.<\/p>\n<p>Innanzitutto, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9cf10f4aadbe54f2fc2e87b619a33bcc#file-03-admin-style-subscriber-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">l&#8217;abbonato al foglio di stile dell&#8217;amministratore<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of the WordPress Widget Boilerplate\n *\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com?\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace WordPressWidgetBoilerplateSubscriber;\n\n\/**\n * The subscriber responsible for loading the stylesheet on the Widget administration page.\n *\/\nclass AdminStyleAssetSubscriber extends AbstractSubscriber\n{\n    \/**\n     * {@inheritdoc}\n     *\/\n    public function __construct(string $hook)\n    {\n        parent::__construct($hook);\n    }\n\n    \/**\n     * Adds the administrative stylesheet to the widget administration page.\n     *\/\n    public function load()\n    {\n        if ('widgets' !== get_current_screen()-&gt;id) {\n            return;\n        }\n\n        wp_enqueue_style(\n            'wordpress-widget-boilerplate',\n            plugin_dir_url(dirname(__DIR__)).'assets\/css\/admin.css'\n        );\n    }\n}\n<\/code><\/pre>\n<p>Nota che questo utilizza la funzione <a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/get_current_screen\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">get_current_screen()<\/a> che ho usato nei post precedenti per assicurarmi di aggiungere dipendenze solo dove necessario.<\/p>\n<p>Ora, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9cf10f4aadbe54f2fc2e87b619a33bcc#file-05-public-style-subscriber-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">l&#8217;abbonato JavaScript pubblico<\/a>. Questo utilizza la funzione <a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/is_admin\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">is_admin()<\/a> per assicurarci di non essere nell&#8217;area amministrativa di WordPress.<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of the WordPress Widget Boilerplate\n *\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com&gt;\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace WordPressWidgetBoilerplateSubscriber;\n\n\/**\n * The subscriber responsible for loading the stylesheet on the blog.\n *\/\nclass PublicStyleAssetSubscriber extends AbstractSubscriber\n{\n    \/**\n     * {@inheritdoc}\n     *\/\n    public function __construct(string $hook)\n    {\n        parent::__construct($hook);\n    }\n\n    \/**\n     * Adds the stylesheet to the public-facing side of the site.\n     *\/\n    public function load()\n    {\n        if (is_admin()) {\n            return;\n        }\n\n        wp_enqueue_style(\n            'wordpress-widget-boilerplate',\n            plugin_dir_url(dirname(__DIR__)).'assets\/css\/widget.css'\n        );\n    }\n}\n<\/code><\/pre>\n<p>Ovviamente, dobbiamo ancora creare un&#8217;istanza di queste classi. Arriver\u00e0 pi\u00f9 avanti nella serie.<\/p>\n<h5>JavaScript<\/h5>\n<p>Gli abbonati JavaScript non sono molto diversi, come avrai intuito. Li separeremo in base all&#8217;area dell&#8217;applicazione in cui si concentrano e li denomineremo in modo appropriato.<\/p>\n<p>Innanzitutto, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9cf10f4aadbe54f2fc2e87b619a33bcc#file-02-admin-script-subscriber-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">l&#8217;abbonato JavaScript admin<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of the WordPress Widget Boilerplate\n *\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com&gt;\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace WordPressWidgetBoilerplateSubscriber;\n\n\/**\n * The subscriber responsible for loading the JavaScript on the Widget's adminsitration page.\n *\/\nclass AdminScriptAssetSubscriber extends AbstractSubscriber\n{\n    \/**\n     * {@inheritdoc}\n     *\/\n    public function __construct(string $hook)\n    {\n        parent::__construct($hook);\n    }\n\n    \/**\n     * Adds the administrative JavaScript to the widget administration page.\n     *\/\n    public function load()\n    {\n        if ('widgets' !== get_current_screen()-&gt;id) {\n            return;\n        }\n\n        wp_enqueue_script(\n            'wordpress-widget-boilerplate',\n            plugin_dir_url(dirname(__DIR__)).'assets\/js\/admin.js'\n        );\n    }\n}\n<\/code><\/pre>\n<p>E <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9cf10f4aadbe54f2fc2e87b619a33bcc#file-04-public-script-subscriber-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">l&#8217;abbonato JavaScript pubblico:<\/a><\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of the WordPress Widget Boilerplate\n *\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com&gt;\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace WordPressWidgetBoilerplateSubscriber;\n\n\/**\n * The subscriber responsible for loading the JavaScript on the blog.\n *\/\nclass PublicScriptAssetSubscriber extends AbstractSubscriber\n{\n    \/**\n     * {@inheritdoc}\n     *\/\n    public function __construct(string $hook)\n    {\n        parent::__construct($hook);\n    }\n\n    \/**\n     * Adds the JavaScript to the public-facing side of the site.\n     *\/\n    public function load()\n    {\n        if (is_admin()) {\n            return;\n        }\n\n        wp_enqueue_script(\n            'wordpress-widget-boilerplate',\n            plugin_dir_url(dirname(__DIR__)).'assets\/js\/widget.js'\n        );\n    }\n}\n<\/code><\/pre>\n<p>Ancora una volta, queste classi non possono ancora essere istanziate, ma ci concentreremo su questo in un prossimo post.<\/p>\n<h2>Astrazioni e interfacce<\/h2>\n<p>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&#8217;interfaccia implementer\u00e0 tutti i metodi.<\/p>\n<p>Le classi astratte, d&#8217;altra parte, possono avere alcune funzionalit\u00e0 implementate nella classe astratta lasciando il codice specifico del dominio, come il caricamento di fogli di stile e JavaScript, al metodo appropriato.<\/p>\n<p>Questo diventer\u00e0 evidente, se non lo \u00e8 gi\u00e0, pi\u00f9 ci addentreremo in questa serie. Nel frattempo, e come al solito, non dimenticare di controllare il ramo di <a href=\"https:\/\/github.com\/tommcfarlin\/WordPress-Widget-Boilerplate\/tree\/develop\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">sviluppo<\/a> per vedere a che punto siamo con il codice.<\/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>Probabilmente, il problema pi\u00f9 grande con Boilerplate \u00e8 che tutto \u00e8 incapsulato all&#8217;interno di una singola classe. Quindi cambiamo questo con classi astratte.<\/p>\n","protected":false},"author":1,"featured_media":235804,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[835,804,720,865],"tags":[1168],"class_list":["post-231469","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-guida-per-principianti","category-php-6","category-sviluppatore","category-wordpress-6","tag-affiai-it"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/231469","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=231469"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/231469\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media\/235804"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media?parent=231469"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/categories?post=231469"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/tags?post=231469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}