{"id":229144,"date":"2022-10-18T11:48:00","date_gmt":"2022-10-18T08:48:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229144"},"modified":"2022-11-09T05:42:13","modified_gmt":"2022-11-09T02:42:13","slug":"utilizzo-delleditor-blocchi-di-wordpress-gutenberg-con-lapi-rest","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/it\/utilizzo-delleditor-blocchi-di-wordpress-gutenberg-con-lapi-rest\/","title":{"rendered":"Utilizzo dell&#8217;editor blocchi di WordPress (Gutenberg) con l&#8217;API REST"},"content":{"rendered":"\n<p>Nel mio precedente articolo ho parlato di <a href=\"https:\/\/wholesomecode.ltd\/articles\/wp_query-and-the-wordpress-block-editor-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">come scorrere i post e i tipi di post personalizzati all&#8217;interno di Gutenberg<\/a>. In questo post parlo della ricezione e dell&#8217;utilizzo di dati personalizzati all&#8217;interno di Gutenberg dagli endpoint dell&#8217;API REST di WordPress.<\/p>\n<p>In questo esempio andremo a:<\/p>\n<p><strong>L&#8217;API REST non \u00e8 sempre la strada giusta.<\/strong><\/p>\n<p>*Utilizziamo <code>get_option<\/code>solo nell&#8217;API REST come esempio. Se hai solo bisogno dell&#8217;accesso a un&#8217;opzione e non intendi cambiarne lo stato, puoi invece utilizzare <code>wp_localize_script<\/code>per passare le opzioni in JavaScript.<\/p>\n<p>Se vuoi accedere a un&#8217;opzione E cambiarne lo stato, ti consiglio di leggere la mia <a href=\"https:\/\/wholesomecode.ltd\/guides\/options-settings-data-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">guida sulla memorizzazione di impostazioni e dati nella tabella delle opzioni con Gutenberg utilizzando l&#8217;API delle impostazioni<\/a> .*<\/p>\n<h2>Creazione di un endpoint API REST<\/h2>\n<p>Creeremo un semplice endpoint API REST che restituisca il valore di un&#8217;opzione WordPress (usando <code>get_option<\/code>).<\/p>\n<pre><code>function wcltd_get_option() {\n    register_rest_route(\n        'wcltd\/wholesome-plugin\/v1',\n        '\/get\/option\/(?P&lt;option&gt;([A-Za-z0-9_])+)\/',\n        array(\n            'callback'            =&gt; function ($request) {\n                $option = isset( $request['option'] )? esc_attr( $request['option'] ): null;\n                $value  = get_option( $option, '' );\n                return $value;\n            },\n            'methods'             =&gt; 'GET',) );\n}\nadd_action( 'rest_api_init', 'wcltd_get_option' );\n<\/code><\/pre>\n<p>Dopo aver creato questo endpoint, assicurati di <strong>salvare nuovamente i tuoi permalink<\/strong> in modo che si attivino. Nota che ci sono modi migliori per farlo (come usare <code>flush_rewrite_rules()<\/code>su <code>register_activation_hook<\/code>), ma per questo esempio sar\u00e0 sufficiente un rapido salvataggio.<\/p>\n<p>Ora, quando passiamo l&#8217;URL <code>\/wp-json\/wcltd\/wholesome-plugin\/v1\/get\/option\/test\/<\/code>(ovviamente dopo il tuo dominio) nel nostro browser, restituir\u00e0 un valore, che pu\u00f2 essere una stringa vuota <code>''<\/code>o il valore dell&#8217;opzione se impostata.<\/p>\n<p><a href=\"https:\/\/cdn.hashnode.com\/res\/hashnode\/image\/upload\/v1639990082853\/S6umfXuzNF.png\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Il nostro endpoint, restituendo una stringa vuota<\/a> Il nostro endpoint, restituendo una stringa vuota<\/p>\n<p>Nota che ho commentato di proposito le righe 12-14, il che assicurerebbe che solo qualcuno che ha <code>edit_post<\/code>i diritti possa eseguire il codice se lasciato dentro. Tuttavia con questo commento non possiamo testare il codice nel nostro browser.<\/p>\n<p>Prova ad aggiungere del codice per dare un valore alla tua opzione e guarda cosa restituisce. Ad esempio, se dovessi eseguire il seguente codice prima della mia funzione:<\/p>\n<pre><code>update_option( 'wcltd_example_option', 'Hello World' );\n<\/code><\/pre>\n<p>Ora se raggiungo l&#8217;endpoint <code>\/wp-json\/wcltd\/wholesome-plugin\/v1\/get\/option\/wcltd_example_option\/<\/code>otterr\u00f2 il seguente output:<\/p>\n<p>Il nostro endpoint, restituendo alcuni dati.<\/p>\n<h2>Registrazione di un archivio dati<\/h2>\n<p>Ora che abbiamo un endpoint API REST, possiamo creare un datastore con <code>registerStore<\/code>.<\/p>\n<p><code>registerStore<\/code>fornisce un datastore simile a Redux, che ci consente di gestire lo stato nella nostra applicazione. Supporta anche i resolver, che ci consentono di popolare lo stato da un&#8217;origine esterna (come la nostra API REST).<\/p>\n<p>Puoi <a href=\"https:\/\/reactjs.org\/docs\/state-and-lifecycle.html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">leggere di pi\u00f9 sullo stato REACT nella documentazione ufficiale<\/a>.<\/p>\n<p>Ecco come possiamo creare un negozio (come <code>store.js<\/code>nel nostro progetto che ci consentir\u00e0 di estrarre i dati dal nostro endpoint API REST.<\/p>\n<h3>Dipendenze<\/h3>\n<p>Avremo bisogno di estrarre <code>apiFetch<\/code>e <code>registerStore<\/code>dalle nostre dipendenze di WordPress.<\/p>\n<pre><code>import apiFetch from '@wordpress\/api-fetch';\nimport { registerStore } from '@wordpress\/data';\n<\/code><\/pre>\n<h3>Selettori<\/h3>\n<p>La prima cosa che vogliamo fare \u00e8 creare una funzione di selezione, in un oggetto chiamato &#8216;selettori&#8217;.<\/p>\n<p>Tutto ci\u00f2 che fa \u00e8 estrarre l &#8216;&quot;opzione&quot; dallo stato e restituirla.<\/p>\n<pre><code>const selectors = {\n    getOption( state, optionKey) {\n        const { option } = state;\n        return option;\n    },\n};\n<\/code><\/pre>\n<h3>Risolutori<\/h3>\n<p>Il resolver \u00e8 un effetto collaterale del selettore e fa un po&#8217; di pi\u00f9.<\/p>\n<p>Qui creiamo la nostra funzione che prende la nostra optionKey e passa un endpoint API REST alle nostre azioni (che definiremo in seguito).<\/p>\n<p>Questo quindi imposta l&#8217;opzione, con un altro invito alle nostre azioni.<\/p>\n<pre><code>const resolvers = {\n    *getOption( optionKey) {\n        const option = yield actions.getOption(\n            '\/wcltd\/wholesome-plugin\/v1\/get\/option\/' + optionKey + '\/',\n        );\n        return actions.setOption( option );\n    },\n};\n<\/code><\/pre>\n<h3>Azioni<\/h3>\n<p>Le due funzioni in un oggetto denominato <code>actions<\/code>che abbiamo chiamato in precedenza sono definite qui.<\/p>\n<p>Indicano quale controllo o riduttore utilizzeremo per impostare o ottenere il valore.<\/p>\n<pre><code>const actions = {\n    setOption( option) {\n        return {\n            type: 'SET_OPTION',\n            option,\n        };\n    },\n    getOption( path) {\n        return {\n            type: 'GET_OPTION',\n            path,\n        };\n    },\n};\n<\/code><\/pre>\n<h3>Controlli<\/h3>\n<p>Nei nostri controlli abbiamo <code>GET_OPTION<\/code>che effettua la chiamata API utilizzando <code>apiFetch<\/code>e il percorso che abbiamo definito in precedenza.<\/p>\n<pre><code>const controls = {\n    GET_OPTION( action) {\n        return apiFetch( { path: action.path } );\n    },\n};\n<\/code><\/pre>\n<h3>Riduttore<\/h3>\n<p>Nella nostra funzione riduttore abbiamo <code>SET_OPTION<\/code>che prende il nostro valore (in questo caso <code>option<\/code>, e ne imposta lo stato.<\/p>\n<pre><code>function reducer( state = { option: '' }, action) {\n    switch (action.type) {\n        case 'SET_OPTION':\n            return {\n                ...state,\n                option: action.option,\n            };\n    }\n    return state;\n};\n<\/code><\/pre>\n<h3>Registrazione del negozio<\/h3>\n<p>Infine, registriamo un negozio, gli diamo uno spazio dei nomi in modo da potervi accedere e passiamo un oggetto di tutti gli oggetti e le funzioni sopra indicati.<\/p>\n<pre><code>const store = registerStore(\n    'wcltd\/wholesome-plugin\/data',\n    {\n        actions,\n        controls,\n        reducer,\n        resolvers,\n        selectors,\n    }\n);\n\nexport default store;\n<\/code><\/pre>\n<p>esporta il negozio predefinito;<\/p>\n<h2>Utilizzo dei dati con un blocco<\/h2>\n<p>Espandiamo il <a href=\"https:\/\/wholesomecode.ltd\/articles\/an-overview-of-the-wordpress-create-block-script\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">blocco creato dallo <code>@wordpress\/create-block<\/code>script, di cui ho scritto in precedenza<\/a> per consentirci di connetterci a un endpoint API REST.<\/p>\n<p>Crea un file nella <code>\/src<\/code>cartella chiamata <code>store.js<\/code>e copiaci tutto il codice sopra:<\/p>\n<pre><code>import apiFetch from '@wordpress\/api-fetch';\nimport { registerStore } from '@wordpress\/data';\n\nconst selectors = {\n    getOption( state, optionKey) {\n        const { option } = state;\n        return option;\n    },\n};\n\nconst resolvers = {\n    *getOption( optionKey) {\n        const option = yield actions.getOption(\n            '\/wcltd\/wholesome-plugin\/v1\/get\/option\/' + optionKey + '\/',\n        );\n        return actions.setOption( option );\n    },\n};\n\nconst actions = {\n    setOption( option) {\n        return {\n            type: 'SET_OPTION',\n            option,\n        };\n    },\n    getOption( path) {\n        return {\n            type: 'GET_OPTION',\n            path,\n        };\n    },\n};\n\nconst controls = {\n    GET_OPTION( action) {\n        return apiFetch( { path: action.path } );\n    },\n};\n\nfunction reducer( state = { option: '' }, action) {\n    switch (action.type) {\n        case 'SET_OPTION':\n            return {\n                ...state,\n                option: action.option,\n            };\n    }\n    return state;\n};\n\nconst store = registerStore(\n    'wcltd\/wholesome-plugin\/data',\n    {\n        actions,\n        controls,\n        reducer,\n        resolvers,\n        selectors,\n    }\n);\n\nexport default store;\n<\/code><\/pre>\n<p>Ora modifica il nostro <code>\/src\/index.js<\/code>file per includere il <code>store.js<\/code>file:<\/p>\n<pre><code>\nimport store from '.\/store';\nimport Edit from '.\/edit';\nimport save from '.\/save';\n<\/code><\/pre>\n<p>Dobbiamo anche assicurarci di aver incluso <code>withSelect<\/code>nella parte superiore del nostro file:<\/p>\n<pre><code>import { withSelect } from '@wordpress\/data';\n<\/code><\/pre>\n<p>Quindi avvolgiamo il nostro modulo Modifica con <code>withSelect<\/code>per effettuare la chiamata API REST alla nostra opzione, in questo modo:<\/p>\n<pre><code>\nedit: withSelect( (select) =&gt; {\n    const option = select( 'wcltd\/wholesome-plugin\/data' ).getOption( 'wcltd_example_option' );\n    return {\n        option,\n    };\n} )( Edit ),\n<\/code><\/pre>\n<p>Ora possiamo accedere <code>option<\/code>ai nostri oggetti di scena all&#8217;interno di <code>edit.js<\/code>, in questo modo:<\/p>\n<pre><code>export default function Edit( { className, option }) {\n    return (&lt;p className={ className }&gt;\n            { option }\n        &lt;\/p&gt;\n    );\n}\n<\/code><\/pre>\n<p>Infine, vediamo il nostro blocco nell&#8217;editor e vediamo cosa otteniamo:<\/p>\n<p><a href=\"https:\/\/cdn.hashnode.com\/res\/hashnode\/image\/upload\/v1639990090843\/2uT6sdoTo.png\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">L&#8217;output nell&#8217;editor di blocchi.<\/a> L&#8217;output nell&#8217;editor di blocchi.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte di registrazione:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/wholesomecode.ltd\" class=\"external external_icon\">wholesomecode.ltd<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nel mio precedente articolo ho parlato di come scorrere i post e i tipi di post personalizzati all&#8217;interno di Gutenberg. In questo post parlo della ricezione e dell&#8217;utilizzo di dati personalizzati all&#8217;interno di Gutenberg f&#8230;<\/p>\n","protected":false},"author":1,"featured_media":220671,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[918,896,720,865],"tags":[1168],"class_list":["post-229144","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-altro","category-codice","category-sviluppatore","category-wordpress-6","tag-affiai-it"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/229144","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=229144"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/229144\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media\/220671"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media?parent=229144"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/categories?post=229144"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/tags?post=229144"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}