Siete ancora perplessi su Gutenberg? Oppure siete tra quelli che credono fermamente nelle potenzialità dell’editor dei blocchi e vogliono scoprire fino a che punto sia possibile spingere la propria creatività?

Qualunque sia la categoria di utenti in cui rientrate, Gutenberg è qui per restare e questo articolo vi offrirà una panoramica approfondita di quello che succede dietro le quinte dell’editor dei blocchi di WordPress. Ma non è tutto!

Dopo il nostro precedente tutorial in cui abbiamo offerto un’introduzione generale allo sviluppo dei blocchi di Gutenberg, questo articolo va oltre le basi, introducendo tipi di blocchi più avanzati. Questi blocchi sono chiamati blocchi dinamici.

Oggi scoprirete cosa sono i blocchi dinamici, come funzionano e tutto ciò che c’è da sapere per creare blocchi dinamici da zero.

Allora, cosa sono i blocchi dinamici di Gutenberg e quali sono le differenze principali tra blocchi statici e dinamici?

Cosa Sono i Blocchi Dinamici? Un Esempio

Mentre con i blocchi statici il contenuto viene aggiunto manualmente dall’utente durante la modifica di un post o di una pagina, con i blocchi dinamici il contenuto viene caricato ed elaborato al volo al caricamento della pagina. Con i blocchi dinamici, il contenuto del blocco viene prelevato dal database e visualizzato così com’è o come risultato di un qualsiasi tipo di manipolazione dei dati.

Spieghiamolo con un esempio. Supponiamo di voler creare un gruppo di blocchi annidati che mostrino i dettagli dell’autore del post e una selezione degli ultimi post dello stesso autore.

Un blocco Gruppo che include l'autore del post e gli ultimi post
Un blocco Gruppo che include l’autore del post e gli ultimi post

Come utenti di Gutenberg, potete utilizzare i seguenti blocchi:

  • Il blocco core Intestazione
  • Il blocco core Autore del post
  • Il blocco core Ultimi Articoli

Potreste anche creare un gruppo che includa questi blocchi e aggiungere il gruppo ai blocchi riutilizzabili per un utilizzo futuro.

Aggiungere un blocco Gruppo a blocchi riutilizzabili
Aggiungere un blocco Gruppo a blocchi riutilizzabili

È abbastanza semplice, non è vero? È possibile creare un blocco dinamico e aggiungerlo ai vostri post e alle vostre pagine in un attimo.

A partire da WordPress 5.9, l’editor dei blocchi offre più di 90 blocchi diversi: è probabile che troverete il blocco che fa per voi. E se ne volete altri, fate una veloce ricerca nella directory dei plugin di WordPress e troverete molti plugin gratuiti che forniscono altri blocchi.

Ma cosa succede se siete uno sviluppatore di WordPress o se state pianificando una carriera come sviluppatori WordPress? Forse avete esigenze molto specifiche e non riuscite a trovare il blocco che state cercando, oppure volete semplicemente acquisire nuove competenze professionali. In queste situazioni, potreste voler imparare a creare i vostri blocchi dinamici.

I Blocchi Dinamici di Gutenberg dal Punto di Vista degli Sviluppatori

I blocchi dinamici hanno due casi d’uso principali.

Il primo caso d’uso è quando dovete aggiornare il contenuto di un blocco quando la pagina che lo contiene non è stata aggiornata. Ad esempio, questo accade quando il blocco include un elenco degli ultimi post o commenti e, in generale, quando il contenuto del blocco viene generato dinamicamente utilizzando i dati recuperati dal database.

Aggiunta di un blocco Query Loop
Aggiunta di un blocco Query Loop

Il secondo caso d’uso è quando un aggiornamento del codice del blocco deve essere immediatamente visualizzato sul front-end. Utilizzando un blocco dinamico invece di un blocco statico, le modifiche vengono applicate immediatamente a tutte le occorrenze del blocco.

D’altro canto, se modificate l’HTML prodotto da un blocco statico, l’utente vedrà una finestra di dialogo di invalidazione fino a quando ogni singola istanza della versione precedente del blocco non verrà rimossa e sostituita con la nuova versione, oppure fino a quando avrete contrassegnato la vecchia versione come deprecata (vedi anche Deprecation e Block Validation, Deprecation and Migration Experience).

Contenuto inatteso o non valido.
Contenuto inatteso o non valido.

Detto questo, ci sono alcuni concetti che bisogna comprendere prima di iniziare a costruire blocchi dinamici.

Stato dell’Applicazione e Data Store

Gutenberg è un’applicazione SPA React e tutto in Gutenberg è un componente React. Il titolo del post, le intestazioni, i paragrafi, le immagini e qualsiasi blocco di contenuto HTML presente nell’editor sono componenti React, così come lo sono i controlli della barra laterale e della barra degli strumenti dei blocchi.

Nel nostro precedente articolo, per memorizzare i dati abbiamo utilizzato solo le proprietà. In questo articolo faremo un passo avanti introducendo il concetto di stato.

In parole semplici, l’oggetto state è un semplice oggetto JavaScript utilizzato per contenere informazioni su un componente. Lo state del componente può cambiare nel tempo e ogni volta che cambia, il componente viene reso nuovamente.

Analogamente all’oggetto state, le proprietà sono semplici oggetti JavaScript utilizzati per contenere informazioni sul componente. Ma c’è una differenza fondamentale tra proprietà e state:

Le props vengono passate al componente (come i parametri di una funzione) mentre lo state viene gestito all’interno del componente (come le variabili dichiarate all’interno di una funzione).

Potete pensare allo stato come a un’istantanea di dati, presi in un determinato momento, che un’applicazione memorizza per controllare il comportamento di un componente. Ad esempio, se la barra laterale delle impostazioni dell’editor di blocchi è aperta, un’informazione sarà memorizzata da qualche parte nell’oggetto state.

Quando le informazioni sono condivise all’interno di un singolo componente, si parla di local state. Quando le informazioni sono condivise tra i componenti di un’applicazione, si parla di Application State.

Lo Stato dell’Applicazione è strettamente legato al concetto di store. Secondo la documentazione di Redux:

Uno store contiene l’intero albero di stato dell’applicazione. L’unico modo per cambiare lo stato al suo interno è inviare un’azione su di esso.

Quindi, Redux memorizza lo stato di un’applicazione in un unico albero di oggetti immutabile (ovvero uno store). L’albero degli oggetti può essere modificato solo creando un nuovo oggetto utilizzando azioni e riduttori.

In WordPress, gli store sono gestiti dal modulo data di WordPress.

Modularità, Pacchetti e Archivi di Dati in Gutenberg

Il repository di Gutenberg è costruito da zero su diversi moduli riutilizzabili e indipendenti che, combinati insieme, creano l’interfaccia di editing. Questi moduli sono chiamati anche pacchetti.

La documentazione ufficiale elenca due diversi tipi di pacchetti:

  • I pacchetti di produzione costituiscono il codice di produzione che viene eseguito nel browser. In WordPress esistono due tipi di pacchetti di produzione:
    • I pacchetti con fogli di stile forniscono fogli di stile per funzionare correttamente.
    • I pacchetti con archivi di dati definiscono gli archivi di dati per la gestione dello stato. I pacchetti con archivi di dati possono essere utilizzati da plugin e temi di terze parti per recuperare e manipolare i dati.
  • I pacchetti di sviluppo sono utilizzati in modalità di sviluppo. Questi pacchetti includono strumenti per il linting, il testing, il building, ecc.

In questo caso ci interessano soprattutto i pacchetti con i data store, utilizzati per recuperare e manipolare i dati.

Il Data Store di WordPress

Il Data Store di WordPress è costruito su Redux e condivide i tre principi fondamentali di Redux, anche se con alcune differenze fondamentali.

La documentazione ufficiale fornisce la seguente definizione:

Il modulo Data di WordPress funge da hub per la gestione dello stato dell’applicazione sia per i plugin che per lo stesso WordPress, fornendo strumenti per la gestione dei dati all’interno e tra moduli distinti. È stato progettato come modello modulare per l’organizzazione e la condivisione dei dati: abbastanza semplice da soddisfare le esigenze di un piccolo plugin, ma allo stesso tempo scalabile per soddisfare i requisiti di una complessa applicazione a pagina singola.

Di default, Gutenberg registra diversi data store all’interno dello stato dell’applicazione. Ognuno di questi archivi ha un nome e uno scopo specifici:

Attraverso questi archivi, potrete accedere a una serie di dati:

  1. Dati relativi al post corrente, come il titolo del post, l’estratto, le categorie e i tag, i blocchi, ecc.
  2. Dati relativi all’interfaccia utente, ad esempio se un interruttore è attivato o disattivato.
  3. Dati relativi all’intera installazione di WordPress, come le tassonomie registrate, i tipi di post, il titolo del blog, gli autori, ecc.

Questi store risiedono nell’oggetto globale wp. Per accedere allo stato di un archivio, si utilizzerà la funzione select.

Per vedere come funziona, create un nuovo post o una nuova pagina e lanciate l’inspector del browser. Trovate la console e digitate la seguente riga di codice:

wp.data.select("core")

Il risultato sarà un oggetto che include un elenco di funzioni che potete utilizzare per ottenere i dati dal Data Store core. Queste funzioni sono chiamate selettori e agiscono come interfacce per accedere ai valori dello stato.

L'oggetto Core del data store di WordPress
L’oggetto Core del data store di WordPress

Il data store di WordPress include informazioni su WordPress in generale e i selettori sono il modo per ottenere queste informazioni. Ad esempio, getCurrentUser() restituisce i dati dell’utente corrente:

wp.data.select("core").getCurrentUser()
Ispezione della risposta di getCurrentUser
Ispezione della risposta di getCurrentUser

Un altro selettore utile per recuperare i dati dell’utente dall’archivio dati è getUsers() :

wp.data.select("core").getUsers()

L’immagine seguente mostra l’oggetto della risposta:

Ispezione della risposta di getUsers
Ispezione della risposta di getUsers

Per ottenere i dati di un singolo utente, basta digitare la seguente riga:

wp.data.select("core").getUsers()[0]

Utilizzando lo stesso selettore, è anche possibile recuperare gli utenti del sito con il ruolo author:

wp.data.select( 'core' ).getUsers({ who: 'authors' })

Potete anche recuperare le tassonomie registrate:

wp.data.select("core").getTaxonomies()
Ispezione della risposta di getTaxonomies.
Ispezione della risposta di getTaxonomies.

Un elenco dei tipi di post registrati:

wp.data.select("core").getPostTypes()

Oppure un elenco di plugin:

wp.data.select("core").getPlugins()

Ora proviamo ad accedere a un data store diverso. Per farlo, utilizzerete ancora la funzione select, ma fornendo un diverso namespace. Proviamo a fare come segue:

wp.data.select("core/edit-post")

Ora otterrete il seguente oggetto di risposta.

Accedere ai dati dell'interfaccia utente dell'editor
Accedere ai dati dell’interfaccia utente dell’editor

Se volete sapere se la barra laterale delle impostazioni è aperta o meno, utilizzate il selettore isEditorSidebarOpened:

wp.data.select("core/edit-post").isEditorSidebarOpened()

Questa funzione restituisce true se la barra laterale è aperta:

La barra laterale è aperta.
La barra laterale è aperta.

Come Accedere ai Dati dei Post

Ora dovreste avere le nozioni di base per accedere ai dati e possiamo analizzare più da vicino un selettore specifico, la funzione getEntityRecords, che è il selettore che dà accesso ai dati del post.

Nell’editor dei blocchi, fate clic con il tasto destro del mouse e selezionate Ispeziona. Nella scheda Console, copiate e incollate la seguente riga:

wp.data.select("core").getEntityRecords('postType', 'post')

Questo invia una richiesta alla Rest API e restituisce un array di record corrispondenti agli ultimi post pubblicati sul blog.

getEntityRecords restituisce un elenco di post.
getEntityRecords restituisce un elenco di post.

getEntityRecords accetta tre parametri:

  • kind stringa: Tipo di entità (es. postType).
  • name stringa: Nome dell’entità (es. post).
  • query oggetto: Query di termini opzionale (es. {author: 0}).

Potete creare richieste più specifiche utilizzando un oggetto di argomenti.

Ad esempio, potete decidere che la risposta debba contenere solo i post di una determinata categoria:

wp.data.select("core").getEntityRecords('postType', 'post', {categories: 3})

Potete anche richiedere solo articoli di un determinato autore:

wp.data.select("core").getEntityRecords('postType', 'post', {author: 2})

Se fate clic su uno dei record restituiti da getEntityRecords, otterrete un elenco delle proprietà del record selezionato:

Un esempio di richiesta API con getEntityRecords.
Un esempio di richiesta API con getEntityRecords.

Se volete che la risposta includa l’immagine in primo piano, dovrete aggiungere un ulteriore argomento alla richiesta precedente:

wp.data.select("core").getEntityRecords('postType', 'post', {author: 2, _embed: true})
Dati dell'immagine in primo piano nella risposta di getEntityRecords.
Dati dell’immagine in primo piano nella risposta di getEntityRecords.

Ora dovreste aver compreso bene come accedere al datastore di WordPress e recuperare i dati dei post. Per una visione più approfondita del selettore getEntityRecords, si veda anche Requesting data in Gutenberg with getEntityRecords.

Come Creare un Blocco Dinamico: Un Progetto di Esempio

Dopo la nostra lunga premessa teorica, possiamo passare alla pratica e creare un blocco dinamico utilizzando gli strumenti che abbiamo introdotto nel nostro precedente tutorial sullo sviluppo dei blocchi.

Nel precedente articolo abbiamo parlato di:

  1. Come Configurare un Ambiente di Sviluppo WordPress
  2. Cos’è un Block Scaffolding
  3. Come Costruire un Blocco Statico di Gutenberg

Per questo motivo non tratteremo questi argomenti in modo approfondito nel presente articolo, ma fate riferimento alla nostra guida precedente per qualsiasi informazione aggiuntiva o semplicemente per un ripasso.

Configurare un Ambiente di Sviluppo JavaScript

Iniziamo con la configurazione di un ambiente di sviluppo JavaScript.

Installare o Aggiornare Node.js

Per prima cosa, installate o aggiornate Node.js. Una volta terminato, lanciate il vostro strumento a riga di comando ed eseguite quanto segue:

node -v

Dovreste vedere la vostra versione di Node.

Configurare l’Ambiente di Sviluppo

Successivamente, avrete bisogno di un ambiente di sviluppo per WordPress. Per i nostri esempi abbiamo utilizzato DevKinsta, il nostro strumento di sviluppo WordPress gratuito che permette di lanciare un sito WordPress locale in pochissimo tempo.

Creare un sito personalizzato in DevKinsta
Creare un sito personalizzato in DevKinsta

Ma siete comunque liberi di scegliere qualsiasi ambiente di sviluppo locale di WordPress, come MAMP o XAMPP, o anche la soluzione ufficiale wp-env.

Se state usando DevKinsta, fate clic su Nuovo Sito WordPress o su Sito Personalizzato, compila i campi del modulo e premete Crea sito.

Il processo di installazione richiede uno o due minuti. Al termine, avviate il vostro sito WordPress di sviluppo locale.

Schermata delle informazioni sul sito in DevKinsta.
Schermata delle informazioni sul sito in DevKinsta.

Configurare il Plugin del Blocco

Ora vi serve un plugin del blocco iniziale. Per evitare il fastidio di una configurazione manuale, il team di sviluppatori di WordPress ha rilasciato lo strumento @wordpress/create-block, che è lo strumento ufficiale a configurazione zero per la creazione di blocchi Gutenberg.

Abbiamo trattato in modo approfondito @wordpress/create-block nel nostro precedente articolo, quindi possiamo iniziare subito la configurazione.

Nel vostro strumento a riga di comando, spostatevi nella cartella /wp-content/plugins:

New terminal at folder in Mac OS.
New terminal at folder in Mac OS.

Una volta lì, eseguite il seguente comando:

npx @wordpress/create-block

Ora siete pronti per installare il pacchetto @wordpress/create-block:

Installazione del pacchetto @wordpress/create-block.
Installazione del pacchetto @wordpress/create-block.

Per confermare, digitate y e premete Invio.

Questo genera i file PHP, SCSS e JS del plugin in modalità interattiva.

Di seguito sono riportati i dati che utilizzeremo nel nostro esempio. Modificate questi dati in base alle vostre preferenze:


Una volta premuto invio, il plugin viene scaricato e configurato.

Installazione del plugin del blocco.
Installazione del plugin del blocco.

Il processo potrebbe richiedere un paio di minuti. Al termine, dovreste vedere la seguente schermata:

Blocco avviato nella cartella dei plugin.
Blocco avviato nella cartella dei plugin.

Vedrete un elenco dei comandi che potete eseguire dalla cartella dei plugin:

  • $ npm start – Avvia la build per lo sviluppo.
  • $ npm run build – Crea il codice per la produzione.
  • $ npm run format – Formatta i file.
  • $ npm run lint:css – Controlla i file CSS.
  • $ npm run lint:js – Controlla i file JavaScript.
  • $ npm run packages-update – Aggiorna i pacchetti di WordPress all’ultima versione.

Ok, ora spostatevi nella cartella dei plugin con il seguente comando:

cd author-plugin

E avviate la vostra build di sviluppo:

npm start

Successivamente, accedi alla schermata dei plugin nella vostra dashboard di WordPress e attivate il plugin Author box:

Il plugin del blocco è elencato nella schermata dei plugin.
Il plugin del blocco è elencato nella schermata dei plugin.

Ora potete verificare se il plugin funziona correttamente. Create un nuovo post e inizia a digitare / per lanciare l’inseritore rapido:

L'elemento blocco nell'inseritore rapido.
L’elemento blocco nell’inseritore rapido.

Il blocco Author box si trova anche nel Block Inserter, sotto la categoria Widgets. Selezionate il blocco per aggiungerlo all’editor:

Il Block Inserter di WordPress.
Il Block Inserter di WordPress

E il gioco è fatto. Ora salvate il post e visualizzate l’anteprima della pagina per verificare che il blocco venga visualizzato correttamente.

L’Impalcatura dei Blocchi

Abbiamo trattato l’impalcatura dei blocchi (block scaffolding) nel nostro precedente articolo. Quindi, qui forniremo solo una rapida panoramica dei file che modificheremo nei nostri esempi.

La Cartella Principale
Nella cartella principale si trovano il file PHP principale e diverse sottocartelle.

author-plugin.php
Di default, il pacchetto @wordpress/create-block genera il seguente file PHP:

/**
 * Plugin Name:       Author box
 * Description:       An example block for Kinsta readers
 * Requires at least: 5.8
 * Requires PHP:      7.0
 * Version:           0.1.0
 * Author:            Carlo
 * License:           GPL-2.0-or-later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain:       author-plugin
 *
 * @package           author-box
 */

/**
 * Registers the block using the metadata loaded from the `block.json` file.
 * Behind the scenes, it registers also all assets so they can be enqueued
 * through the block editor in the corresponding context.
 *
 * @see https://developer.wordpress.org/reference/functions/register_block_type/
 */
function author_box_author_plugin_block_init() {
	register_block_type( __DIR__ . '/build' );
}
add_action( 'init', 'author_box_author_plugin_block_init' );

Nell’intestazione, noterete i dati che abbiamo inserito al momento della configurazione.

Con i blocchi statici, lavorerete per la maggior parte del tempo sui file JavaScript che si trovano nella cartella src. Con i blocchi dinamici, scriverete il codice PHP per visualizzare il contenuto del blocco sul front-end.

La Cartella src
La cartella src è la cartella di sviluppo. Qui troverete i seguenti file:

  • block.json
  • index.js
  • edit.js
  • save.js
  • editor.scss
  • style.scss

block.json
Il file block.json è il file dei metadati. @wordpress/create-block genera il seguente file block.json:

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 2,
	"name": "author-box/author-plugin",
	"version": "0.1.0",
	"title": "Author box",
	"category": "widgets",
	"icon": "businessperson",
	"description": "An example block for Kinsta readers",
	"supports": {
		"html": false
	},
	"textdomain": "author-plugin",
	"editorScript": "file:./index.js",
	"editorStyle": "file:./index.css",
	"style": "file:./style-index.css"
}

Per una visione più approfondita del file block.json in generale, consultate il nostro precedente articolo.

index.js
Il file index.js è il punto in cui si registra il tipo di blocco sul client:

import { registerBlockType } from '@wordpress/blocks';

import './style.scss';

import Edit from './edit';
import save from './save';

registerBlockType('author-box/author-plugin', {
	edit: Edit,
	save,
});

edit.js
Il file edit.js è dove costruirete l’interfaccia del blocco visualizzata nell’editor:

import { __ } from '@wordpress/i18n';

import { useBlockProps } from '@wordpress/block-editor';

import './editor.scss';

export default function Edit() {
	return (
		<p {...useBlockProps()}>
			{__('Author box – hello from the editor!', 'author-plugin')}
		</p>
	);
}

save.js
Il file save.js contiene lo script che crea il contenuto del blocco da salvare nel database. In questo tutorial non utilizzeremo questo file:

import { __ } from '@wordpress/i18n';

import { useBlockProps } from '@wordpress/block-editor';

export default function save() {
	return (
		<p {...useBlockProps.save()}>
			{__('Author box – hello from the saved content!', 'author-plugin')}
		</p>
	);
}

Creare il Blocco da Rendere nell’Editor

Aprite il vostro progetto in Visual Studio Code o in qualsiasi altro editor di codice.

Se state usando Visual Studio Code, andate su Terminale -> Nuovo Terminale. In questo modo si aprirà una finestra del terminale nella cartella principale del progetto.

Nel terminale (o nel vostro strumento a riga di comando preferito), digitate il seguente comando:

npm start

Ora state eseguendo l’ambiente node in modalità di sviluppo.

Il progetto del plugin del blocco in Visual Studio Code.
Il progetto del plugin del blocco in Visual Studio Code.

Da qui in poi, seguirete due strade diverse. Per rendere il blocco nell’editor, lavorerete nel file edit.js. Per rendere il blocco sul front-end, dovrete scrivere del codice PHP nel file principale del plugin.

Ora rimbocchiamoci le maniche perché iniziamo con il codice:

Registriamo il Blocco sul Server

Per prima cosa, dovete registrare il blocco sul server e scrivere il codice PHP per recuperare i dati dal database.

Nel file author-plugin.php, dovrete passare un secondo argomento alla funzione register_block_type:

function author_box_author_plugin_block_init() {
	register_block_type( __DIR__ . '/build', array(
		'render_callback' => 'author_box_author_plugin_render_author_content'
	) );
}
add_action( 'init', 'author_box_author_plugin_block_init' );

Il secondo parametro è un array di argomenti per la registrazione di un tipo di blocco (vedi l’elenco completo degli argomenti disponibili). Nel codice qui sopra abbiamo fornito solo render_callback, che determina la funzione di callback che rende il blocco sullo schermo.

Poi dichiarerete la funzione:

function author_box_author_plugin_render_author_content() {
	return 'Hello World!';
}

Salvate il file, create un nuovo post o una nuova pagina e aggiungete il blocco Author Box al canvas dell’editor.

Il Block Inserter di WordPress.
Il Block Inserter di WordPress.

L’editor dei blocchi mostra ancora il blocco iniziale, dato che non abbiamo ancora modificato il file edit.js.

Ma se visualizzate l’anteprima del post nel front-end, vedrete che il contenuto del blocco originale è stato sostituito dalla stringa “Hello World”.

Ora, dato che l’HTML reso sul front-end è generato dal file PHP, non sarà necessario che la funzione save restituisca qualcosa. Andiamo quindi direttamente al file save.js e modifichiamo il codice come mostrato di seguito:

export default function save() {
	return null;
}

Definiamo gli Attributi del Blocco

Ora avete bisogno di un posto dove memorizzare le impostazioni dell’utente. Ad esempio, il numero di post da recuperare dal database, se visualizzare o meno un campo specifico, ecc. Per farlo, dovrete definire una serie di attributes nel file block.json.

Ad esempio, potete dare all’utente la possibilità di stabilire il numero di post da includere nel blocco, l’opzione di visualizzare l’immagine principale, la data, l’estratto e/o di nascondere/mostrare l’immagine del profilo dell’autore.

Ecco l’elenco completo degli attributi che utilizzeremo per creare il nostro blocco di esempio:

{
	...
	"attributes": {
		"numberOfItems": {
			"type": "number",
			"default": 3
		},
		"columns": {
			"type": "number",
			"default": 1
		},
		"displayDate": {
			"type": "boolean",
			"default": true
		},
		"displayExcerpt": {
			"type": "boolean",
			"default": true
		},
		"displayThumbnail": {
			"type": "boolean",
			"default": true
		},
		"displayAuthorInfo": {
			"type": "boolean",
			"default": true
		},
		"showAvatar": {
			"type": "boolean",
			"default": true
		}, 
		"avatarSize": {
			"type": "number",
			"default": 48
		},
		"showBio": {
			"type": "boolean",
			"default": true
		}
	}
}

Il Blocco da Visualizzare nell’Editor

Il selettore getEntityRecords è incluso nel pacchetto @wordpress/data. Per utilizzarlo, dovrete importare l’hook useSelect di quel pacchetto nel vostro file edit.js:

import { useSelect } from '@wordpress/data';

Quindi, aggiungete il seguente codice alla funzione Edit():

const posts = useSelect( ( select ) => {
	return select( 'core' ).getEntityRecords( 'postType', 'post', {
		'per_page': 3
	});
});

Nel codice precedente abbiamo inserito il numero di post. Ma potreste voler dare agli utenti la possibilità di impostare un numero diverso di post. A tal fine potete utilizzare un attributo.

Nel vostro block.json dovreste aver definito un attributo numberOfItems. È possibile utilizzarlo nella funzione Edit come mostrato di seguito:

export default function Edit( { attributes } ) {

	const { numberOfItems } = attributes;

	const posts = useSelect( ( select ) => {
		return select( 'core' ).getEntityRecords( 'postType', 'post', {
			'per_page': numberOfItems
		});
	});

	console.log( posts );

	return (
		...
	);
}

Non vedrete ancora i post sullo schermo, ma eseguite un console.log e guardate cosa succede nella console dell’ispector del browser:

Il risultato nella console del browser.
Il risultato nella console del browser.

useSelect accetta due argomenti: una callback in linea e un array di dipendenze. Entrambi restituiscono una versione memoizzata della callback che cambia solo quando cambia una delle dipendenze.

Quindi, per recuperare i post ad ogni modifica dell’attributo numberOfItems, dovrete modificare la funzione Edit come mostrato di seguito:

export default function Edit( { attributes } ) {

	const { numberOfItems } = attributes;

	const posts = useSelect(
		( select ) => {
			return select( 'core' ).getEntityRecords( 'postType', 'post', {
				'per_page': numberOfItems
			});
		}, 
		[ numberOfItems ]
	);

	console.log(posts);

	return (
		...
	);
}

Poi dovrete eseguire il rendering dell’elenco dei post. Per farlo, potete utilizzare il metodo JavaScript integrato map:

export default function Edit( { attributes } ) {

	const { numberOfItems } = attributes;

	const posts = useSelect(
		( select ) => {
			return select( 'core' ).getEntityRecords( 'postType', 'post', {
				'per_page': numberOfItems
			});
		},
		[ numberOfItems ]
	);

	console.log(posts);
	
	return (
		<div { ...useBlockProps() }>
			<ul>
				{ posts && posts.map( ( post ) => {
					return (
						<li key={ post.id }>
							<h5>
								<a href={ post.link }>
									{ 
										post.title.rendered ? 
										post.title.rendered :
										__( 'Default title', 'author-plugin' )
									}
								</a>
							</h5>
						</li>
					)
				})}
			</ul>
		</div>
	);
}

Per prima cosa, questo codice controlla se c’è almeno un post nell’array, quindi esegue il ciclo.

Si noti che, dato che stiamo utilizzando il metodo map con un componente React, stiamo anche utilizzando un attributo key per assegnare l’ID del post all’elemento corrente dell’elenco.

post.link e post.title.rendered rendono rispettivamente l’URL e il titolo del post.

L’immagine seguente mostra l’elenco completo delle proprietà dell’oggetto post.

L'oggetto Post.
L’oggetto Post.

Il codice qui sopra è solo un esempio di base di getEntityRecords. Ora è il momento di mettere in pratica le nostre conoscenze.

Supponiamo di voler evitare che il vostro blocco renda i tag HTML che l’utente potrebbe aver aggiunto al titolo del post. A questo scopo, WordPress mette a disposizione un componente RawHTML.

Per prima cosa, dovrete importare il componente dal pacchetto @wordpress/element:

import { RawHTML } from '@wordpress/element';

Poi, racchiuderete il titolo del post in un elemento RawHTML:

<div { ...useBlockProps() }>
	<ul>
		{ posts && posts.map((post) => {
			return (
				<li key={ post.id }>
					<h5>
						<a href={ post.link }>
							{ post.title.rendered ? (
								<RawHTML>
									{ post.title.rendered }
								</RawHTML>
							) : (
								__( 'Default title', 'author-plugin' )
							)}
						</a>
					</h5>
				</li>
			)
		})}
	</ul>
</div>

E questo è tutto. Ora aggiungete un tag HTML al titolo del post e salvatelo. Poi provate il vostro codice con e senza RawHTML e guardate come cambia il contenuto del vostro blocco sullo schermo.

Aggiungiamo la Data

WordPress fornisce una serie di funzioni JavaScript per gestire e formattare le date. Per utilizzare queste funzioni bisogna prima importarle dal pacchetto @wordpress/date nel file edit.js:

import { dateI18n, format, __experimentalGetSettings } from '@wordpress/date';
  • dateI18n: Formatta una data, traducendola nel locale del sito.
  • format: Formatta una data.
  • __experimentalGetSettings: Visualizza la data nel formato impostato nelle impostazioni generali di WordPress.

Queste funzioni non sono documentate, ma troverete utili esempi nel codice sorgente di diversi blocchi. Si vedano ad esempio i file edit.js di latest-posts e post-date.

Ora aggiungete l’attributo displayDate:

const { numberOfItems, displayDate } = attributes;

Quindi aggiungete il seguente codice all’interno dell’elemento <li>:

{ 
	displayDate && (
		<time
			className='wp-block-author-box-author-plugin__post-date'
			dateTime={ format( 'c', post.date_gmt ) }
		>
			{ dateI18n(
				__experimentalGetSettings().formats.date, 
				post.date_gmt
			)}
		</time>
	) 
}

Cosa succede qui?

Aggiungiamo il Riassunto

Ora dovrebbe essere facile aggiungere l’estratto del post. Per prima cosa, date un’occhiata alla proprietà excerpt nell’ispector del browser. Vedrete che il contenuto effettivo è memorizzato in excerpt.rendered.

Ispezione dell'estratto del post in Chrome DevTools.
Ispezione dell’estratto del post in Chrome DevTools.

Quindi aggiungete l’attributo displayExcerpt all’oggetto attributes:

const { numberOfItems, displayDate, displayExcerpt } = attributes;

Poi aggiungete il seguente codice prima del tag di chiusura </li> nella funzione Edit:

{
	displayExcerpt &&
	post.excerpt.rendered && (
		<p>
			<RawHTML>
				{ post.excerpt.rendered }
			</RawHTML>
		</p>
	)
}

Se non avete dimestichezza con JavaScript, qui e sopra abbiamo utilizzato la Short Circuit Evaluation, in base alla quale, se tutte le condizioni sono vere, viene restituito il valore dell’ultimo operando (per saperne di più, si legga Inline If with Logical && Operator e Logical AND (&&)).

Quindi testate nuovamente il vostro codice. Cambiate il valore dell’attributo nel file block.json e guardate cosa succede nell’editor.

Aggiungiamo l’Immagine in Primo Piano

Ora dovete aggiungere il codice che rende le immagini in primo piano. Iniziate aggiungendo l’attributo displayThumbnail a attributes:

const { 
	numberOfItems, 
	displayDate, 
	displayExcerpt, 
	displayThumbnail 
} = attributes;

Ora dovete capire dove viene memorizzata l’immagine in primo piano. Come abbiamo detto sopra, per ottenere l’immagine in primo piano bisogna aggiungere un nuovo argomento _embed alla query. Tornate al vostro codice e modificate gli argomenti della query come segue:

const posts = useSelect(
	( select ) => {
		return select( 'core' ).getEntityRecords( 'postType', 'post', {
			'per_page': numberOfItems,
			'_embed': true
		});
	},
	[ numberOfItems ]
);

Qui abbiamo semplicemente aggiunto '_embed': true all’array di argomenti. In questo modo si ottiene un oggetto post che contiene la proprietà _embedded, la quale fornisce i dettagli dell’immagine di cui avete bisogno per visualizzare le immagini in primo piano.

Ora dovreste sapere dove trovare i dati delle immagini.

Dati dell'immagine in primo piano nella risposta di getEntityRecords.
Dati dell’immagine in primo piano nella risposta di getEntityRecords.

Dovete solo aggiungere il codice che rende l’immagine sullo schermo:

{
	displayThumbnail && 
	post._embedded && 
	post._embedded['wp:featuredmedia'] &&
	post._embedded['wp:featuredmedia'][0] &&
	<img 
	className='wp-block-author-box-author-plugin__post-thumbnail'
		src={ post._embedded['wp:featuredmedia'][0].media_details.sizes.medium.source_url }
		alt={ post._embedded['wp:featuredmedia'][0].alt_text }
	/>
}

Salvate il file, passate all’editor dei blocchi e verificate se l’immagine viene visualizzata correttamente quando l’attributo displayThumbnail è impostato su true.

Un elenco di post con immagine in evidenza, data ed estratto.
Un elenco di post con immagine in evidenza, data ed estratto.

I Controlli della Barra Laterale

Finora abbiamo utilizzato i valori predefiniti degli attributi impostati nel file block.json. Ma dall’articolo precedente sappiamo che possiamo definire dei gestori di eventi per dare agli utenti la possibilità di assegnare valori personalizzati a ogni attributo.

Per farlo, aggiungerete una serie di controlli alla barra laterale delle impostazioni del blocco. In edit.js, importate i seguenti componenti dai pacchetti corrispondenti:

import { 
	useBlockProps,
	InspectorControls
} from '@wordpress/block-editor';

import {
	PanelBody,
	PanelRow,
	QueryControls,
	ToggleControl,
	RangeControl
} from '@wordpress/components';
  • InspectorControls: contiene le impostazioni della barra laterale che riguardano l’intero blocco (vedi su GitHub)
  • PanelBody: aggiunge un contenitore a scomparsa alla barra laterale delle impostazioni (vedi su GitHub)
  • PanelRow: produce un contenitore generico per i controlli della barra laterale (vedi su GitHub)
  • QueryControls: fornisce i controlli delle impostazioni per costruire una query (vedi su GitHub)
  • ToggleControl: fornisce un pulsante di attivazione/disattivazione di un’opzione specifica per gli utenti (vedi su GitHub)
  • RangeControl: viene utilizzato per effettuare selezioni da una gamma di valori incrementali (vedi su GitHub)

Dovete quindi aggiornare la funzione Edit per utilizzare i controlli ora disponibili. Per prima cosa, modificate la funzione Edit come segue:

export default function Edit( { attributes, setAttributes } ) {

	const { 
		numberOfItems, 
		columns, 
		displayExcerpt, 
		displayDate, 
		displayThumbnail
	} = attributes;

	const posts = useSelect(
		( select ) => {
			return select( 'core' ).getEntityRecords( 'postType', 'post', {
				'per_page': numberOfItems,
				'_embed': true
			});
		},
		[ numberOfItems ]
	);
	...
}

Si noti la proprietà setAttributes passata alla funzione Edit.

Ora potete aggiungere gli elementi corrispondenti al vostro codice JSX:

return (
	<>
		<InspectorControls>
			<PanelBody title={ __( 'Content Settings', 'author-plugin' ) }>
				<PanelRow>
					<QueryControls 
						numberOfItems={ numberOfItems }
						onNumberOfItemsChange={ ( value ) =>
							setAttributes( { numberOfItems: value } )
						}
						minItems={ 1 }
						maxItems={ 10 }
					/>
				</PanelRow>
				<PanelRow>
					<RangeControl
						label={ __( 'Number of Columns', 'author-plugin' ) }
						value={ columns }
						onChange={ ( value ) =>
							setAttributes( { columns: value } )
						}
						min={ 1 }
						max={ 4 }
						required
					/>
				</PanelRow>
				<PanelRow>
					<ToggleControl
						label={ __( 'Show Featured Image', 'author-plugin' ) }
						checked={ displayThumbnail }
						onChange={ () =>
							setAttributes( { displayThumbnail: ! displayThumbnail } )
						}
					/>
				</PanelRow>
				<PanelRow>
					<ToggleControl
						label={ __( 'Show Date', 'author-plugin' ) }
						checked={ displayDate }
						onChange={ () =>
							setAttributes( { displayDate: ! displayDate } )
						}
					/>
				</PanelRow>
				<PanelRow>
					<ToggleControl
						label={ __( 'Display Excerpt', 'author-plugin' ) }
						checked={ displayExcerpt }
						onChange={ () =>
							setAttributes( { displayExcerpt: ! displayExcerpt } )
						}
					/>
				</PanelRow>
			</PanelBody>
		</InspectorControls>
		<div { ...useBlockProps() }>
			...
		</div>
	</>
);

Se state pensando che è un sacco di codice… è vero! Ma è piuttosto facile da capire.

Gli attributi dell’elemento che meritano maggiormente la nostra attenzione sono onNumberOfItemsChange in QueryControls e onChange in RangeControl e ToggleControl. Questi attributi impostano i gestori di eventi necessari per consentire all’utente di personalizzare l’aspetto e/o il comportamento di un blocco.

Noterete anche che abbiamo utilizzato i tag <> e </>, che sono la sintassi breve per dichiarare i frammenti di React.

Ora salvate il file, passate all’editor e aggiornate la pagina:

Impostazioni del blocco.
Impostazioni del blocco.

C’è tutto? Allora andiamo avanti e aggiungiamo i dati dell’autore del post.

L’Autore del Post

Come abbiamo detto sopra, il nostro blocco mostrerà un elenco di articoli scritti dallo stesso autore del post corrente.

Per ottenere l’ID dell’autore del post, è necessario importare il selettore getCurrentPostAttribute dal datastore core/editor:

wp.data.select( 'core/editor' ).getCurrentPostAttribute( 'author' )

getCurrentPostAttribute restituisce il valore di un attributo per il post salvato.

Una volta ottenuto l’ID dell’autore, potrete modificare la query come mostrato di seguito:

const posts = useSelect(
	( select ) => {

		const _authorId = select( 'core/editor' ).getCurrentPostAttribute( 'author' );
	
		return select( 'core' ).getEntityRecords( 'postType', 'post', {
			'author': _authorId,
			'per_page': numberOfItems,
			'_embed': true
		});
	},
	[ numberOfItems ]
);

Con questo codice otterrete un elenco di n articoli dello stesso autore del post corrente.

Ora che avete l’ID dell’autore, potete usarlo anche per recuperare altri dati dal database.

Visualizzare i Dati dell’Autore

Dato che non abbiamo a disposizione alcuna documentazione, abbiamo utilizzato il codice del blocco core Post Author come riferimento.

Per visualizzare i dati dell’autore, dovete prima importare una nuova dipendenza:

import { forEach } from 'lodash';

Poi, nella funzione Edit, aggiornate l’oggetto attributes come segue:

const { 
	numberOfItems, 
	columns, 
	displayExcerpt, 
	displayDate, 
	displayThumbnail, 
	displayAuthorInfo, 
	showAvatar, 
	avatarSize, 
	showBio 
} = attributes;

Una volta fatto, modificherete il codice visto nella sezione precedente per recuperare i dati dell’autore:

const { authorDetails, posts } = useSelect(
	( select ) => {

		const _authorId = select( 'core/editor' ).getCurrentPostAttribute( 'author' );

		const authorDetails = _authorId ? select( 'core' ).getUser( _authorId ) : null;
	
		const posts = select( 'core' ).getEntityRecords( 'postType', 'post', {
			'author': _authorId,
			'per_page': numberOfItems,
			'_embed': true
		});

		return { 
			authorDetails: authorDetails,
			posts: posts
		};
	},
	[ numberOfItems ]
);

Si noti che abbiamo utilizzato il selettore getUser per ottenere i dati dell’autore.

Successivamente, potreste voler ottenere l’avatar dell’autore. Il codice seguente crea un array di elementi che contengono gli URL e le dimensioni degli avatar:

const avatarSizes = [];
if ( authorDetails ) {
	forEach( authorDetails.avatar_urls, ( url, size ) => {
		avatarSizes.push( {
			value: size,
			label: `${ size } x ${ size }`,
		} );
	} );
}

Poi aggiungerete i pannelli e i controlli della barra laterale per consentire agli utenti di personalizzare l’area dell’autore nel blocco:

return (
	<>
		<InspectorControls>
			<PanelBody title={ __( 'Author Info', 'author-plugin' ) }>
				<PanelRow>
					<ToggleControl
						label={ __( 'Display Author Info', 'author-plugin' ) }
						checked={ displayAuthorInfo }
						onChange={ () =>
							setAttributes( { displayAuthorInfo: ! displayAuthorInfo } )
						}
					/>
				</PanelRow>
				{ displayAuthorInfo && (
					<>
						<PanelRow>
							<ToggleControl
								label={ __( 'Show avatar' ) }
								checked={ showAvatar }
								onChange={ () =>
									setAttributes( { showAvatar: ! showAvatar } )
								}
							/>
							{ showAvatar && (
								<SelectControl
									label={ __( 'Avatar size' ) }
									value={ avatarSize }
									options={ avatarSizes }
									onChange={ ( size ) => {
										setAttributes( {
											avatarSize: Number( size ),
										} );
									} }
								/>
							) }
						</PanelRow>
						<PanelRow>
							<ToggleControl
								label={ __( 'Show Bio', 'author-plugin' ) }
								checked={ showBio }
								onChange={ () =>
									setAttributes( { showBio: ! showBio } )
								}
							/>
						</PanelRow>
					</>
				) }
			</PanelBody>
			...
		</InspectorControls>
		...
	</>
);

L’immagine qui sotto mostra la barra laterale delle impostazioni aggiornata:

Il pannello delle impostazioni delle Info Autore.
Il pannello delle impostazioni delle Info Autore.

Infine, potete aggiungere la sezione dell’autore al vostro blocco:

return (
	<>
		<InspectorControls>
		...
		</InspectorControls>

		<div { ...useBlockProps() }>
			{ displayAuthorInfo  && authorDetails && (
				<div className="wp-block-author-box-author-plugin__author">
					{ showAvatar && (
						<div className="wp-block-author-box-author-plugin__avatar">
							<img
								width={ avatarSize }
								src={
									authorDetails.avatar_urls[
										avatarSize
									]
								}
								alt={ authorDetails.name }
							/>
						</div>
					) }
					<div className='wp-block-author-box-author-plugin__author-content'>
						<p className='wp-block-author-box-author-plugin__name'>
							{ authorDetails.name }
						</p>
						{ showBio &&
							// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
							authorDetails?.description &&
							authorDetails.description.length > 0 && (
							<p className='wp-block-author-box-author-plugin__description'>{ authorDetails.description }</p>
						) }
					</div>
				</div>
			)}
			<ul>
			...
			</ul>
		</div>
	</>
);

L’immagine che segue mostra cosa viene visualizzato sullo schermo.

Sezione dei dati dell'autore.
Sezione dei dati dell’autore.

Ora salvate il file edit.js ed eseguite i test. Il vostro blocco dovrebbe includere elementi diversi a seconda delle impostazioni del blocco.

I dati dell'autore non mostrano la biografia.
I dati dell’autore non mostrano la biografia.

Manca ancora un’ultima cosa: il numero di colonne per la visualizzazione degli articoli.

Cambiamo il Numero di Colonne

Per dare all’utente la possibilità di mostrare le anteprime degli articoli in colonne, abbiamo definito l’attributo columns nel file block.json. Abbiamo anche incluso un attributo columns nello script e creato un controllo delle impostazioni per consentire agli utenti di modificare il numero di colonne, anche se questa modifica non ha alcun effetto al momento.

Nel codice JSX precedente dovreste aver notato che abbiamo aggiunto delle classi CSS a diversi elementi:

Classi assegnate agli elementi della sezione Autore:

  • wp-block-author-box-author-plugin__author
  • wp-block-author-box-author-plugin__avatar
  • wp-block-author-box-author-plugin__author-content
  • wp-block-author-box-author-plugin__name
  • wp-block-author-box-author-plugin__description

Classi assegnate agli elementi della sezione Contenuto:

  • wp-block-author-box-author-plugin__post-items
  • wp-block-author-box-author-plugin__post-thumbnail
  • wp-block-author-box-author-plugin__post-title
  • wp-block-author-box-author-plugin__post-date
  • wp-block-author-box-author-plugin__post-excerpt

Manca ancora una classe. Il nome di questa classe sarà generato dinamicamente per riflettere il numero di colonne impostato dall’utente.

Tornate al file Edit.js e modificate l’elemento ul come segue:

<ul className={ `wp-block-author-box-author-plugin__post-items columns-${ columns }` }>
	...
</ul>

Abbiamo aggiunto una nuova classe columns-${ columns } secondo la sintassi dei Template literals per inserire un’espressione all’interno di una stringa. In questo modo, l’attributo collegato all’elemento ul dipenderà dalle impostazioni dell’utente (ad esempio columns-1, columns-2, ecc.).

Ora aprite il file style.scss e sostituite il codice esistente con il seguente:

.wp-block-author-box-author-plugin {
	background-color: #21759b;
	color: #fff;
	padding: .6em;
	ul.wp-block-author-box-author-plugin__post-items {
		padding: 0;
		list-style-type: none;
		display: grid;
		gap: .5em;
		@for $i from 2 through 4 {
			&.columns-#{ $i } {
				grid-template-columns: repeat(#{ $i }, 1fr);
			}
		}
		li {
			list-style: none;
			img.wp-block-author-box-author-plugin__post-thumbnail {
				height: auto;
				max-width: 100%;
			}
		}
		
	}
}
.wp-block-author-box-author-plugin__author {
	display: flex;
    flex-wrap: wrap;
}

.wp-block-author-box-author-plugin__avatar {
	margin-right: 1em;
}

.wp-block-author-box-author-plugin__author-content {
	flex-basis: 0;
    flex-grow: 1;
}

Non ci addentreremo in questo codice perché non rientra negli scopi di questo articolo. Ma chi volesse approfondire può fare riferimento alle seguenti risorse:

Il blocco Autore nell'editor.
Il blocco Autore nell’editor.

E questo è tutto per il rendering del blocco nell’editor.

Creare il Blocco da Rendere sulla Pagina

Ora che il codice per il rendering del blocco nell’editor è completo, possiamo passare a costruire il blocco per il rendering sul front-end.

Come abbiamo detto in precedenza, quando si tratta di blocchi dinamici, il file del plugin è responsabile della generazione dell’HTML da renderizzare sul front-end.

Quindi, aprite il file principale del vostro plugin (author-plugin.php nel nostro esempio).

La prima cosa da fare è rendere disponibili gli attributi del blocco alla funzione PHP di WordPress. Nel vostro file PHP, modificate la definizione della funzione come segue:

function author_box_author_plugin_render_author_content( $attr ) {
	...
}

Ora potete utilizzare le funzioni di WordPress per recuperare e manipolare i dati. Ad esempio, potete utilizzare get_posts per recuperare gli ultimi articoli del blog (per saperne di più, si legga il nostro articolo di approfondimento sulla funzioneget_posts):

function author_box_author_plugin_render_author_content( $attr ) {
	$args = array(
		'numberposts'	=> $attr['numberOfItems'],
	);
	$my_posts = get_posts( $args );
	
	if( ! empty( $my_posts ) ){
		$output = '<ul>';
		foreach ( $my_posts as $p ){
			$output .= '<li><a href="' . esc_url( get_permalink( $p->ID ) ) . '">' 
			. $p->post_title . '</a></li>';
		}
		$output .= '</ul>';
	}
	return $output ?? '<strong>Sorry. No posts matching your criteria!</strong>';
}

La funzione qui sopra recupera gli ultimi numberOfItems post del blog dal database di WordPress (di default post_type è impostato su post) e restituisce un array di oggetti $post. Poi itera sull’array per costruire gli elementi dell’elenco.

Se ispezionate l’output HTML, noterete che si tratta di un semplice elenco di post, come quello mostrato nell’immagine che segue:

Un semplice elenco di post.
Un semplice elenco di post.

Nell’articolo precedente abbiamo accennato all’utilizzo dell’hook React useBlockProps per contrassegnare l’elemento wrapper del blocco nel codice JSX. Dovrete fare lo stesso nella vostra funzione PHP.

A questo scopo, WordPress mette a disposizione la funzione get_block_wrapper_attributes.

Quindi modificate il vostro codice PHP come segue:

function author_box_author_plugin_render_author_content( $attr ) {
	$args = array(
		'numberposts'	=> $attr['numberOfItems']
	);
	$my_posts = get_posts( $args );
	
	if( ! empty( $my_posts ) ){
		$output = '<div ' . get_block_wrapper_attributes() . '>';
		$output .= '<ul>';
		foreach ( $my_posts as $p ){
			
			$title = $p->post_title ? $p->post_title : 'Default title';
			$url = esc_url( get_permalink( $p->ID ) );

			$output .= '<li>';
			$output .= '<a href="' . $url . '">' . $title . '</a>';
			$output .= '</li>';
		}
		$output .= '</ul>';
		$output .= '</div>';
	}
	return $output ?? '<strong>Sorry. No posts matching your criteria!</strong>';
}

Ora è stata assegnata una classe wp-block-author-box-author-plugin all’elemento container e il blocco ha un colore di sfondo diverso.

La funzione get_posts riceve i dati di WP_Posts e il ciclo foreach costruisce gli elementi dell’elenco (si veda anche Come Visualizzare i Dati Restituiti da get_posts).

Un elenco di post con assegnata una classe CSS.
Un elenco di post con assegnata una classe CSS.

Immagini in Primo Piano, Data ed Estratto

Successivamente, dovrete aggiungere le miniature dei post, le date e gli estratti. Nello stesso file, modificate il codice PHP come segue:

function author_box_author_plugin_render_author_content( $attr ) {
	$args = array(
		'numberposts'	=> $attr['numberOfItems']
	);
	$my_posts = get_posts( $args );
	
	if( ! empty( $my_posts ) ){
		$output = '<div ' . get_block_wrapper_attributes() . '>';
		$output .= '<ul class="wp-block-author-box-author-plugin__post-items columns-">';

		foreach ( $my_posts as $p ){
			
			$title = $p->post_title ? $p->post_title : 'Default title';
			$url = esc_url( get_permalink( $p->ID ) );
			$thumbnail = has_post_thumbnail( $p->ID ) ? get_the_post_thumbnail( $p->ID, 'medium' ) : '';

			$output .= '<li>';
			if( ! empty( $thumbnail ) && $attr['displayThumbnail'] ){
				$output .= $thumbnail;
			}
			$output .= '<h5><a href="' . $url . '">' . $title . '</a></h5>';
			if( $attr['displayDate'] ){
				$output .= '<time datetime="' . esc_attr( get_the_date( 'c', $p ) ) . '">' . esc_html( get_the_date( '', $p ) ) . '</time>';
			}
			if( get_the_excerpt( $p ) && $attr['displayExcerpt'] ){
				$output .= '<p>' . get_the_excerpt( $p ) . '</p>';
			}
			$output .= '</li>';
		}
		$output .= '</ul>';
		$output .= '</div>';
	}
	return $output ?? '<strong>Sorry. No posts matching your criteria!</strong>';
}

Il ciclo foreach esegue l’iterazione dell’array $my_posts. Ad ogni iterazione, diverse condizioni controllano i valori degli attributi e creano l’output di conseguenza.

Ora guardate l’output sullo schermo:

Un elenco di post con immagini in evidenza, date ed estratti.
Un elenco di post con immagini in evidenza, date ed estratti.

Ora potete eseguire i vostri test. Cambiate le impostazioni di date, estratti e miniature e verificate come cambia il contenuto del blocco sul front-end.

Visualizziamo i Post in Colonne

Nel nostro codice JavaScript abbiamo utilizzato una classe columns-${ columns } per visualizzare le anteprime dei post in colonne. Ora dobbiamo fare lo stesso in PHP.

Per farlo, dovete semplicemente aggiungere queste due righe di codice:

$num_cols = $attr['columns'] > 1 ? strval( $attr['columns'] ) : '1';

$output .= '<ul class="wp-block-author-box-author-plugin__post-items columns-' . $num_cols . '">';

Questo aggiungerà una classe columns-n all’elemento ul che contiene le anteprime dei post. Ora il numero di colonne visualizzate nella pagina dovrebbe corrispondere al numero di colonne memorizzato nelle impostazioni del blocco.

Il Riquadro Autore

Infine, dovrete creare il riquadro contenente le informazioni sull’autore, tra cui l’avatar, il nome e la descrizione.

All’interno della funzione di callback, dovrete aggiungere una serie di condizioni per verificare il valore corrente di ogni attributo:

if( $attr['displayAuthorInfo'] ){
	$output .= '<div class="wp-block-author-box-author-plugin__author">';
	
	if( $attr['showAvatar'] ){
		$output .= '<div class="wp-block-author-box-author-plugin__avatar">' 
			. get_avatar( get_the_author_meta( 'ID' ), $attr['avatarSize'] ) 
			. '</div>';
	}

	$output .= '<div class="wp-block-author-box-author-plugin__author-content">';
	
	$output .= '<div class="wp-block-author-box-author-plugin__name">' 
		. get_the_author_meta( 'display_name' ) 
		. '</div>';

	if( $attr['showBio'] ){
		$output .= '<div class="wp-block-author-box-author-plugin__description">' 
			. get_the_author_meta( 'description' ) 
			. '</div>';
	}

	$output .= '</div>';
	$output .= '</div>';
}

Il codice è piuttosto semplice. Controlla il valore corrente di ogni attributo e, se è true, allora genera l’HTML necessario.

Ora salvate il vostro file PHP e confrontate il blocco nell’editor con lo stesso blocco sul front-end.

Il nostro blocco personalizzato nell'editor di blocchi.
Il nostro blocco personalizzato nell’editor di blocchi.

Troverete il codice completo del blocco di esempio in questo Gist pubblico.

Risorse Consigliate per lo Sviluppo di Blocchi Dinamici

Se leggendo questo articolo avete drizzato le orecchie e avete iniziato a riconoscere le opportunità di sviluppo professionale che possono nascere imparando a creare blocchi Gutenberg, il nostro consiglio è quello di continuare a esplorare e acquisire nuove competenze sulle tecnologie alla base dello sviluppo dei blocchi.

Sebbene manchi ancora una documentazione ufficiale completa e affidabile, esistono comunque ottime risorse, sia gratuite che a pagamento, che abbiamo consultato durante la stesura di questo articolo. Tra le tante risorse disponibili, vi consigliamo le seguenti:

Risorse ufficiali

Tutorial Consigliati dai Contributor al Core di WordPress

Risorse su JavaScript, React e Redux

Risorse correlate di Kinsta

Riepilogo

Siamo giunti alla fine di questo (secondo) lungo viaggio nello sviluppo dei blocchi di Gutenberg.

In questo articolo abbiamo trattato alcuni argomenti avanzati, come l’Application State e gli store Redux. Ma speriamo che ora abbiate una migliore comprensione dello sviluppo dei blocchi in generale.

Certo, le competenze su Node.js, Webpack, Babel, React e Redux sono essenziali quando si tratta di costruire blocchi Gutenberg avanzati, ma non è necessario essere un ninja di React per iniziare. Imparare a sviluppare blocchi Gutenberg non deve necessariamente essere complicato. Basta farlo con la giusta motivazione e seguendo un percorso di apprendimento adeguato.

Speriamo che questo articolo e il precedente vi forniscano la mappa giusta per trovare la vostra strada e iniziare subito a sviluppare per Gutenberg.

Ora tocca a voi! Avete già creato dei blocchi dinamici? Avete qualche esempio da condividere con noi? E quali sono stati i maggiori ostacoli nella vostra esperienza? Lasciate un commento qui sotto.

Carlo Daniele Kinsta

Carlo è cultore appassionato di webdesign e front-end development. Gioca con WordPress da oltre 20 anni, anche in collaborazione con università ed enti educativi italiani ed europei. Su WordPress ha scritto centinaia di articoli e guide, pubblicati sia in siti web italiani e internazionali, che su riviste a stampa. Lo trovate su LinkedIn.