{"id":233992,"date":"2023-02-26T18:35:00","date_gmt":"2023-02-26T15:35:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233992"},"modified":"2022-11-11T13:38:54","modified_gmt":"2022-11-11T10:38:54","slug":"crea-e-recupera-endpoint-rest-personalizzati-nei-blocchi-di-gutenberg","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/it\/crea-e-recupera-endpoint-rest-personalizzati-nei-blocchi-di-gutenberg\/","title":{"rendered":"Crea e recupera endpoint REST personalizzati nei blocchi di Gutenberg"},"content":{"rendered":"\n<p>In questo post cercher\u00f2 di creare una panoramica su come creare endpoint API REST personalizzati ed eseguire richieste per essi in un blocco Gutenberg personalizzato. Cio\u00e8, fare richieste con <code>fetch<\/code>metodi per informazioni non disponibili negli archivi dati registrati di WordPress.<\/p>\n<p>Un promemoria amichevole: la maggior parte delle informazioni di base sono gi\u00e0 disponibili nei datastore di WordPress. Ad esempio, le query di base su post, pagine, tipi di post personalizzati, tassonomie, autori, media e altro sono disponibili cos\u00ec come sono senza dover creare i propri endpoint personalizzati. Per accedere a questi negozi, preferisci utilizzare il modulo dati core di WordPress (<code>withSelect<\/code>e <code>select()<\/code>). Di seguito \u00e8 riportato un tutorial che approfondisce come farlo.<\/p>\n<h2>API REST di WordPress<\/h2>\n<p>Se non lo sapevi gi\u00e0; L&#8217;API REST di WordPress \u00e8 un&#8217;interfaccia JSON per inviare e ricevere dati dal tuo sito WordPress. Pu\u00f2 essere utilizzato esternamente o internamente. Con l&#8217;editor Gutenberg e il passaggio a Javascript, l&#8217;utilizzo dell&#8217;API REST \u00e8 decisamente aumentato. L&#8217;API REST di WordPress ha un sacco di endpoint che possiamo utilizzare. Consulta un <a href=\"https:\/\/developer.wordpress.org\/rest-api\/reference\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">riferimento completo su tutti gli endpoint dell&#8217;API REST qui<\/a>. Troverai ad esempio gli endpoint per i post e la maggior parte degli altri contenuti interni, sia per la lettura che per l&#8217;aggiornamento. Gli sviluppatori di temi o plugin possono registrare i propri endpoint personalizzati.<\/p>\n<p>Il tuo sito WordPress ha un URL API REST radice, come predefinito situato in <code>&lt;your domain&gt;\/wp-json<\/code>. Ad esempio, un WordPress locale con l&#8217;URL <code>http:\/\/localhost\/wordpress\/<\/code>pu\u00f2 accedere all&#8217;API REST all&#8217;indirizzo <code>http:\/\/localhost\/wordpress\/wp-json<\/code>. Da l\u00ec dobbiamo aggiungere gli endpoint. Facendo riferimento al riferimento sopra degli endpoint, possiamo recuperare un elenco degli ultimi post nell&#8217;endpoint <code>\/wp\/v2\/posts<\/code>. Ci\u00f2 significa che se vai <code>http:\/\/localhost\/wordpress\/wp-json\/wp\/v2\/posts<\/code>nel tuo browser otterrai una risposta in formato JSON degli ultimi post nel tuo sito WordPress.<\/p>\n<p>Una nota sugli spazi dei nomi \u00e8 d&#8217;obbligo. Un URL API REST inizia con uno spazio dei nomi (&#8216; <code>wp\/v2<\/code>&#8216; \u00e8 lo spazio dei nomi di WordPress&#8217; come mostrato negli URL di esempio sopra). Namespaces \u00e8 un concetto per evitare conflitti nel core di WordPress, temi e plugin aggiungendo endpoint con lo stesso nome. Crea il tuo spazio dei nomi univoco, in genere una forma slug del tuo tema o nome del plug-in. Dopo lo slug una regola generale consiste nell&#8217;aggiungere il numero di versione, normalmente a partire dalla v1. Ad esempio, lo slug del mio tema \u00e8 &#8216; <code>awhitepixel<\/code>&#8216;, quindi se dovessi creare endpoint personalizzati nel mio tema userei lo spazio dei nomi &#8216; <code>awhitepixel\/v1<\/code>&#8216;. Con questo spazio dei nomi potrei registrare un endpoint &#8216; <code>posts<\/code>&#8216; e non causerebbe problemi anche se \u00e8 identico al nome dell&#8217;endpoint di WordPress.<\/p>\n<p>Lavorare con l&#8217;API REST in WordPress \u00e8 un argomento ampio con molte buone informazioni disponibili. In questo post mi concentrer\u00f2 sull&#8217;usabilit\u00e0 nell&#8217;editor Gutenberg e su come recuperarli in Javascript.<\/p>\n<h2>Cosa faremo e di cosa abbiamo bisogno<\/h2>\n<p>L&#8217;usabilit\u00e0 per la richiesta di informazioni personalizzate ha un&#8217;ampia gamma di casi d&#8217;uso, quindi in genere \u00e8 necessario personalizzare gli esempi di codice seguenti per soddisfare le proprie esigenze. I dati potrebbero essere una query post personalizzata, una query SQL personalizzata o qualcosa di completamente diverso.<\/p>\n<p>Quando creiamo un endpoint personalizzato, abbiamo il pieno controllo del suo ritorno. Possiamo eseguire qualsiasi tipo di operazione e query in WordPress\/PHP e trasmetterlo come JSON. E nel nostro blocco Gutenberg saremo in grado di recuperare questo ritorno e fare ci\u00f2 che vogliamo con esso all&#8217;interno della <code>edit<\/code>funzione del blocco. In genere utilizzeresti i dati per presentare all&#8217;utente finale una scelta o informazioni all&#8217;interno dell&#8217;editor di blocchi, ma puoi anche archiviare le informazioni da essi nel blocco per un ulteriore utilizzo. Puoi anche creare i tuoi archivi personalizzati per questi dati, ma non spiegher\u00f2 come farlo.<\/p>\n<p>Presumo che tu abbia gi\u00e0 familiarit\u00e0 con come creare blocchi Gutenberg personalizzati, quindi non lo esaminer\u00f2 in dettaglio qui.<\/p>\n<h2>Creazione di un endpoint API REST<\/h2>\n<p>La registrazione di un endpoint API REST personalizzato viene eseguita in PHP. Aggiungeresti questo codice nel tuo tema <code>functions.php<\/code>o in un codice plug-in attivo. Collega una funzione all&#8217;azione <code>rest_api_init<\/code>ed esegui la funzione <code>[register_rest_route](https:\/\/developer.wordpress.org\/reference\/functions\/register_rest_route\/)()<\/code>per ogni endpoint che desideri registrare.<\/p>\n<p>Fornisci il tuo spazio dei nomi come primo parametro, la route dell&#8217;endpoint come secondo e una matrice di impostazioni come terzo parametro per <code>register_rest_route()<\/code>. Il quarto parametro controlla se si desidera o meno sovrascrivere un percorso esistente; non qualcosa che vedremo qui. Nell&#8217;array per il terzo parametro dovresti almeno impostare la propriet\u00e0 &#8216; <code>callback<\/code>&#8216; su una funzione responsabile della restituzione dei dati dell&#8217;endpoint. Anche l&#8217;impostazione &#8216; <code>method<\/code>&#8216; \u00e8 comune, ad esempio l&#8217;impostazione dell&#8217;endpoint su &#8216; <code>GET<\/code>&#8216;, &#8216; <code>POST<\/code>&#8216;, &#8216; <code>PUT<\/code>&#8216;, ecc.<\/p>\n<p>Iniziamo con la registrazione di un semplice endpoint;<\/p>\n<pre><code>add_action('rest_api_init', function() {\n    register_rest_route('awhitepixel\/v1', '\/mydata', [\n        'method' =&gt; 'GET',\n        'callback' =&gt; 'awhitepixel_rest_route_mydata'\n    ]);\n});<\/code><\/pre>\n<p>Lo spazio dei nomi del mio tema \u00e8 &quot; <code>awhitepixel\/v1<\/code>&quot; e sto registrando un endpoint &quot; <code>mydata<\/code>&quot; all&#8217;interno di questo spazio dei nomi. Ci\u00f2 significa che posso accedere alla mia API REST personalizzata su <code>http:\/\/localhost\/wordpress\/wp-json\/awhitepixel\/v1\/mydata<\/code>.<\/p>\n<p>Quando registri (o modifichi) i percorsi dell&#8217;API REST, dovrai <strong>svuotare i tuoi permalink<\/strong> affinch\u00e9 funzionino. Puoi farlo visitando Impostazioni &gt; Permalink e facendo semplicemente clic su Salva.<\/p>\n<p>Il codice sopra non funziona ancora, perch\u00e9 non ho definito la funzione impostata come callback: <code>awhitepixel_rest_route_mydata<\/code>. La funzione di callback riceve un parametro; una matrice di dati con informazioni e argomenti passati dalla richiesta. Infine devi considerare attentamente il ritorno della tua funzione di callback.<\/p>\n<p>Innanzitutto devi sempre restituire qualcosa dal callback dell&#8217;endpoint. Qualsiasi reso verr\u00e0 automaticamente convertito in JSON da WordPress. Ci\u00f2 significa che puoi restituire praticamente qualsiasi forma di dati nella tua funzione; una stringa, null, una matrice o <code>[WP_Error](https:\/\/developer.wordpress.org\/reference\/classes\/wp_error\/)<\/code>un&#8217;istanza. Puoi anche optare per la restituzione di un <code>[WP_REST_Response](https:\/\/developer.wordpress.org\/reference\/classes\/wp_rest_response\/)<\/code>oggetto per un maggiore controllo, ad esempio, sul codice di stato o sulle informazioni di intestazione. Raccomando di racchiudere il ritorno nella funzione <code>[rest_ensure_response](https:\/\/developer.wordpress.org\/reference\/functions\/rest_ensure_response\/)()<\/code>per garantire che la tua risposta sia una risposta REST valida.<\/p>\n<p>Definiamo la nostra funzione di callback e restituiamo una semplice stringa come inizio;<\/p>\n<pre><code>function awhitepixel_rest_route_mydata($data) {\n    $response = 'Hello there!';\n    return rest_ensure_response($response);\n}<\/code><\/pre>\n<p>Con il codice sopra (e i permalink scaricati), ora posso andare all&#8217;URL <code>http:\/\/localhost\/wordpress\/wp-json\/awhitepixel\/v1\/mydata<\/code>.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151531-61e4cc06da37f.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-151531-61e4cc06da37f.png\" alt=\"Crea e recupera endpoint REST personalizzati nei blocchi di Gutenberg\" ><\/a><\/p>\n<p>Da qui in poi possiamo aggiungere qualsiasi tipo di codice nella nostra funzione di callback per generare i dati corretti da restituire. Puoi interrogare il contenuto di WordPress con ad es <code>[WP_Query](https:\/\/developer.wordpress.org\/reference\/classes\/wp_query\/)<\/code>, effettuare query nel database o richiedere dati esterni. Questa parte dipende da te.<\/p>\n<p>Ora, passiamo al lato opposto; come fare le richieste.<\/p>\n<h2>Effettuare richieste API REST in Javascript<\/h2>\n<p>L&#8217;esecuzione della richiesta REST viene comunemente eseguita utilizzando <code>[fetch](https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Fetch_API)<\/code>Javascript. WordPress fornisce il proprio wrapper <code>fetch<\/code>che semplifica le richieste dell&#8217;API REST di WordPress; <code>[wp.apiFetch](https:\/\/developer.wordpress.org\/block-editor\/packages\/packages-api-fetch\/)<\/code>. Questo \u00e8 ci\u00f2 che user\u00f2 nel mio blocco Gutenberg personalizzato. Tieni presente che una <code>fetch<\/code>richiesta restituisce una &quot;promessa&quot;, quindi \u00e8 necessario concatenare <code>.then()<\/code>a per gestire l&#8217;effettivo ritorno della richiesta. L&#8217;utilizzo di base \u00e8 qualcosa del genere;<\/p>\n<pre><code>wp.apiFetch({\n    path: '&lt;namespace and endpoint&gt;',\n}).then(data =&gt; {\n    console.log('response from apifetch: ', data);\n});<\/code><\/pre>\n<p><code>apiFetch<\/code>ci consente di fornire una <code>path<\/code>propriet\u00e0 invece di creare l&#8217;URL completo. Tutto ci\u00f2 che dobbiamo fornire \u00e8 lo spazio dei nomi e l&#8217;endpoint e <code>apiFetch<\/code>lo aggiungeremo all&#8217;URL radice dell&#8217;API REST di WordPress. All&#8217;interno della <code>.then()<\/code>funzione abbiamo accesso ai dati che sono gi\u00e0 convertiti in JSON. \u00c8 qui che faresti qualcosa con i dati. Di solito memorizzeresti i dati restituiti, ad esempio, lo stato del componente.<\/p>\n<p>Di seguito \u00e8 riportato un esempio di componente di un blocco Gutenberg personalizzato <code>edit<\/code>. \u00c8 basato sulla classe per essere utilizzato <code>state<\/code>per archiviare i dati restituiti dalla richiesta dell&#8217;API REST. Questo ci consente anche di eseguire la richiesta <code>componentDidMount()<\/code>quando viene montata per la prima volta (consultare <a href=\"https:\/\/reactjs.org\/docs\/state-and-lifecycle.html#adding-lifecycle-methods-to-a-class\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">la documentazione di React sui metodi del ciclo di vita<\/a> ). Tutto ci\u00f2 fornisce un semplice esempio per comprendere il concetto di base; non come ricetta per farlo esattamente cos\u00ec. Potresti prendere in considerazione l&#8217;utilizzo di <a href=\"https:\/\/reactjs.org\/docs\/hooks-intro.html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ganci React e componenti funzionali<\/a> o costruire invece un <a href=\"https:\/\/reactjs.org\/docs\/higher-order-components.html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">componente di ordine superiore<\/a>.<\/p>\n<pre><code>const { Component } = wp.element;\nconst { Spinner } = wp.components;\n\u00a0\nclass BlockEdit extends Component {\n    constructor(props) {\n        super(props);\n        this.state = {\n            list: [],\n            loading: true\n        }\n    }\n\u00a0\n    componentDidMount() {\n        this.runApiFetch();\n    }\n\u00a0\n    runApiFetch() {\n        wp.apiFetch({\n            path: 'awhitepixel\/v1\/mydata',\n        }).then(data =&gt; {\n            this.setState({\n                list: data,\n                loading: false\n            });\n        });\n    }\n\u00a0\n    render() {\n        return(\n            &lt;div&gt;\n                {this.state.loading? (&lt;Spinner \/&gt;\n                ): (&lt;p&gt;Data is ready!&lt;\/p&gt;\n                )}\n            &lt;\/div&gt;\n        );\n\u00a0\n    }\n}\nexport default BlockEdit;<\/code><\/pre>\n<p>L&#8217;esempio sopra \u00e8 un componente basato sulla classe fornito alla <code>edit<\/code>funzione del blocco in <code>registerBlockType()<\/code>. Imposta un oggetto di stato di un array per contenere i dati (questo dipende dai dati restituiti, ovviamente) e uno stato booleano per sapere quando \u00e8 stata restituita la richiesta asincrona. Una volta che il componente \u00e8 montato (renderizzato per la prima volta) esegue la funzione per eseguire la <code>apiFetch<\/code>richiesta. Impostiamo il percorso per l&#8217;endpoint che abbiamo registrato in PHP sopra. Il metodo \u00e8 per impostazione predefinita GET, quindi non \u00e8 necessario specificarlo in <code>apiFetch<\/code>. E all&#8217;interno <code>.then()<\/code>della funzione quando la richiesta \u00e8 pronta aggiorniamo lo stato del componente con i dati restituiti.<\/p>\n<p>Ovviamente la funzione di rendering del tuo blocco farebbe di pi\u00f9 con i dati restituiti stessi. Potresti voler fornire i dati all&#8217;utente in qualche modo presentando un elenco da cui forse scegliere. Tutto dipende da che tipo di dati sono e per cosa li vuoi usare.<\/p>\n<h2>Passaggio di argomenti all&#8217;endpoint<\/h2>\n<p>In alcuni casi \u00e8 necessario passare alcuni argomenti all&#8217;endpoint. Gli usi comuni stanno passando un ID dopo l&#8217;endpoint; ad esempio <code>http:\/\/localhost\/wordpress\/wp-json\/wp\/v2\/posts\/14<\/code>restituirebbe l&#8217;ID del post 14.<\/p>\n<p>Questo \u00e8 piuttosto semplice e viene fatto aggiungendo un modello di ricerca regex all&#8217;endpoint durante la registrazione. Richiede una certa conoscenza delle espressioni regolari per costruire modelli complessi, ma di seguito \u00e8 riportato un esempio che corrisponde a un numero e gli assegna il nome &#8216;id&#8217;. Assegnare un nome alle corrispondenze ci consente di accedere alla variabile nella nostra funzione di callback. Lascia che ti mostri cosa intendo.<\/p>\n<p>Registriamo una nuova route dell&#8217;endpoint. Usiamo lo stesso endpoint di prima (&#8216; <code>awhitepixel\/v1\/mydata<\/code>&#8216;), ma per questo percorso aggiungiamo una corrispondenza regolare per un numero alla fine.<\/p>\n<pre><code>add_action('rest_api_init', function() {\n    register_rest_route('awhitepixel\/v1', '\/mydata', [\n        'method' =&gt; 'GET',\n        'callback' =&gt; 'awhitepixel_rest_route_mydata'\n    ]);\n\u00a0\n    register_rest_route('awhitepixel\/v1', '\/mydata\/(?P&lt;id&gt;[d]+)', [\n        'method' =&gt; 'GET',\n        'callback' =&gt; 'awhitepixel_rest_route_mydata'\n    ]);\n});<\/code><\/pre>\n<p>Il modello regex <code>(?P&lt;id&gt;[d]+)<\/code>sembra criptico, ma sar\u00e0 abbastanza chiaro con alcune nozioni di base sull&#8217;espressione regolare. La <code>[d]+<\/code>parte corrisponde a qualsiasi numero (0-9) 1 o pi\u00f9 volte. Le parti <code>(?P&lt;id&gt;<\/code>e <code>)<\/code>servono per la corrispondenza di un gruppo denominato. Il nome del gruppo \u00e8 in questo caso <code>id<\/code>, ma puoi nominare i tuoi gruppi come preferisci.<\/p>\n<p>Puoi scegliere di indirizzare questo endpoint a una funzione di callback separata, ma ho scelto di utilizzare la stessa funzione per gestire entrambe <code>\/mydata<\/code>le <code>\/mydata\/&lt;ID&gt;<\/code>richieste. Ci\u00f2 significa che posso nella mia funzione di callback fare:<\/p>\n<pre><code>function awhitepixel_rest_route_mydata($data) {\n    if ($data['id']) {\n        $response = 'Create return for ID: '. $data['id'];\n    } else {\n        $response = 'Create general return (no ID provided)';\n    }\n    return rest_ensure_response($response);\n}<\/code><\/pre>\n<p>Ricorda che il parametro della funzione di callback contiene gli argomenti restituiti. Poich\u00e9 ho chiamato il mio gruppo corrispondente &#8216; <code>id<\/code>&#8216;, il valore corrispondente sar\u00e0 accessibile in <code>$data['id']<\/code>. Infine, poich\u00e9 utilizzo la stessa funzione per gestire le richieste con e senza ID, posso passare facilmente tra i due diversi resi.<\/p>\n<p>Con questo (e permalink aggiornati), otterr\u00f2 queste risposte per i miei endpoint personalizzati:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151531-61e4cc079c6de.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-151531-61e4cc079c6de.png\" alt=\"Crea e recupera endpoint REST personalizzati nei blocchi di Gutenberg\" ><\/a><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151531-61e4cc08646fc.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-151531-61e4cc08646fc.png\" alt=\"Crea e recupera endpoint REST personalizzati nei blocchi di Gutenberg\" ><\/a><\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte di registrazione:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Una guida su come creare endpoint API REST di WordPress personalizzati ed eseguire richieste apiFetch per essi in un blocco Gutenberg personalizzato.<\/p>\n","protected":false},"author":1,"featured_media":224922,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[918,896,896,835,939,939,918,1110,814,814,835,844,844,865,865],"tags":[1168],"class_list":["post-233992","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-altro","category-codice","category-guida-per-principianti","category-gutenberg-6","category-n-a","category-plugin-2","category-tutorial","category-wordpress-6","tag-affiai-it"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/233992","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=233992"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/233992\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media\/224922"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media?parent=233992"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/categories?post=233992"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/tags?post=233992"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}