Creare un blocco statico personalizzato in WordPress

Vuoi provare a creare il tuo blocco statico personalizzato per l’editor a blocchi Gutenberg di WordPress?

Ecco una guida passo passo sfruttando il pacchetto  @wordpress/create-block che ti crea una struttura pronta all’uso.

Github Repository

Se vuoi vedere il codice completo del plugin che svilupperemo, lo trovi al link Github del repository.

Prerequisti

Per seguire questo tutorial dovrai avere:

Leggi questa guida approfondita su come preparare un ambiente di sviluppo per i blocchi.

Cosa creeremo

In questa guida creeremo un blocco tempo di lettura, in cui viene mostrato il tempo di lettura stimato di un articolo.

reading time in frontend wordpress

Creare il blocco

Sfruttiamo il pacchetto @wordpress/create-block per creare la struttura del nostro blocco in pochi minuti, che installerà anche un ambiente di sviluppo moderno per JavaScript (usando wp-scripts).

Apri il terminale dalla cartella dei wp-content/plugins/ e scrivi:

npx @wordpress/create-block@latest riaco-reading-time

Partirà la creazione del plugin dal nome riaco-reading-time che conterrà anche un blocco con slug riaco-reading-time.

Ecco la struttura creata:

Questo crea una struttura come:

riaco-reading-time/├── src/
│   └── riaco-reading-time/
│        ├── block.json
│        ├── edit.js
│        ├── editor.scss
│        ├── index.js
│        ├── save.js
│        ├── style.scss
│        └── view.js
├──  package-lock.json
├──  package.json
├──  readme.txt
└──  riaco-reading-time.php

Approfondisci la struttura dei file di un blocco WP.

Ecco quello che vedo nel terminale:

Creating a new WordPress plugin in the C:\xampp\htdocs\test\wp-content\plugins\riaco-reading-time directory.

Creating a "block.json" file.

Creating a "package.json" file.

Installing `@wordpress/scripts` package. It might take a couple of minutes...

Formatting JavaScript files.

Compiling block and generating blocks manifest.

Done: WordPress plugin Riaco Reading Time bootstrapped in the C:\xampp\htdocs\test\wp-content\plugins\riaco-reading-time directory.

Terminata l’installazione troverai la nuova cartella riaco-reading-time in plugins.

Dal terminale digita questo codice per entrare nella cartella del nuovo plugin:

cd riaco-reading-time

Se vai nel pannello di amministrazione di WP > Plugins vedrai il tuo nuovo plugin chiamato Riaco Reading Time.

Attiva il plugin.

Puoi cambiare il nome del plugin e la sua descrizione dal file riaco-reading-time.php.

<?php
/**
 * Plugin Name:       Riaco Reading Time
 * Description:       Example block scaffolded with Create Block tool.
 * Version:           0.1.0
 * Requires at least: 6.7
 * Requires PHP:      7.4
 * Author:            The WordPress Contributors
 * License:           GPL-2.0-or-later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain:       riaco-reading-time
 *
 * @package CreateBlock
 */

Ora crea un articolo di testo e scrivi del testo, anche un lorem ipsum lungo giusto per testare il plugin.

Prova ad inserire il tuo nuovo blocco:

primo blocco in wp

Ecco il tuo primo blocco WordPress!

Ora dobbiamo modificare il codice per aggiungere la nostra funzionalità che calcola il tempo di lettura stimato dell’articolo.

Prima di modificare il blocco

Per modificare il codice ed aggiornare il codice caricato dal plugin, dobbiamo eseguire nel terminale:

npm run start

In questo modo WordPress controllerà le modifiche che verranno effettuate nella cartella src/.

Alla modifica di qualsiasi file dentro questa cartella, WP genererà in automatico nuovi file nella build del plugin che verranno poi usati sul sito.

Se non fai partire questo comando, non vedrai le nuove modifiche che apporterai.

File src/block.json

Il file block.json è il file che contiene tutti i metadati del blocco usati da WordPress.

Dobbiamo aggiungere il supporto ad un nostro attributo (una nostra variabile) minutes che ci servirà dopo per salvare i minuti.

Per farlo aggiungiamo il nostro attributo minutes agli attributi (attributes) del plugin:

"attributes": {
		"minutes": {
			"type": "number",
			"default": 1
		}
	},

I minutes saranno di tipo number e di default è impostato a 1.

Ecco come si presenterà ora il nostro block.json:

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "create-block/riaco-reading-time",
	"version": "0.1.0",
	"title": "Riaco Reading Time",
	"category": "widgets",
	"icon": "smiley",
	"description": "Example block scaffolded with Create Block tool.",
	"example": {},
	"attributes": {
		"minutes": {
			"type": "number",
			"default": 1
		}
	},
	"supports": {
		"html": false
	},
	"textdomain": "riaco-reading-time",
	"editorScript": "file:./index.js",
	"editorStyle": "file:./index.css",
	"style": "file:./style-index.css",
	"viewScript": "file:./view.js"
}

File src/edit.js

Il file edit.js serve a gestire cosa viene mostrato nell’editor a blocchi.

Ecco il codice iniziale del file edit.js:

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';

export default function Edit() {
	return (
		<p { ...useBlockProps() }>
			{ __(
				'Riaco Reading Time – hello from the editor!',
				'riaco-reading-time'
			) }
		</p>
	);
}

Quindi all’inizio vedremo un <p> con delle proprietà gestite in automatico da WP (...useBlockProps()) con all’interno il testo 'Riaco Reading Time – hello from the editor!' (o la sua traduzione).

Che è quello che vediamo nell’immagine sopra.

Ora vogliamo:

  • Leggere il contenuto dell’articolo.
  • Usare il contenuto per estrarre il numero di parole.
  • Usare il contenuto per calcolare il tempo di lettura supponendo un tempo medio di lettura pari a 200 parole/minuto.
  • Mostrare il tempo di lettura calcolato.

Ecco il nuovo codice di edit.js.

import { __ } from "@wordpress/i18n";
import { useSelect } from "@wordpress/data";
import { useEffect } from "@wordpress/element";
import { useBlockProps } from "@wordpress/block-editor";
import "./editor.scss";

export default function Edit({ attributes, setAttributes }) {
	const { minutes } = attributes;

	// Get post content from the editor
	const postContent = useSelect(
		(select) => select("core/editor").getEditedPostContent(),
		[],
	);

	// Calculate reading time (200 wpm)
	const calculateReadingTime = (text) => {
		const stripped = text.replace(/<[^>]+>/g, "").trim();

		if (stripped.length === 0) {
			return 1;
		}

		const words = stripped.split(/\s+/).length;
		return Math.max(1, Math.ceil(words / 200));
	};

	// Recalculate when content changes
	useEffect(() => {
		const newMinutes = calculateReadingTime(postContent);
		if (newMinutes !== minutes) {
			setAttributes({ minutes: newMinutes });
		}
	}, [postContent]);

	const blockProps = useBlockProps({
		className: "riaco-reading-time-block",
	});

	return (
		<p {...blockProps}>
			⏱️ {__("Reading time:", "riaco-reading-time")} {minutes}{" "}
			{__("minutes", "riaco-reading-time")}
		</p>
	);
}

Aggiorna il file edit.js con questo nuovo codice.

Poi fai un refresh dell’editor di WP per ricaricare i file aggiornati del tuo plugin.

Inserisci nuovamente il blocco riaco-reading-time ed ecco comparire il tempo di lettura stimato.

blocco reading time funziona

Funziona!

Vediamo un po’ il codice usato.

useSelect

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

...

const postContent = useSelect(
		(select) => select("core/editor").getEditedPostContent(),
		[],
	);

useSelect: serve a recuperare i dati dello stato globale dell’editor a blocchi, in modo reattivo.

Lo usiamo per leggere il contenuto dell’articolo.

useEffect

import { useEffect } from "@wordpress/element";

...

// Recalculate when content changes
	useEffect(() => {
		const newMinutes = calculateReadingTime(postContent);
		if (newMinutes !== minutes) {
			setAttributes({ minutes: newMinutes });
		}
	}, [postContent]);

useEffect è un React Hook che permette di eseguire codice quando qualcosa cambia o quando un componente si monta.

Nel codice del blocco viene usato per calcolare i minuti di lettura ogni volta che il contenuto del post postContent (che viene usato come dipendenza) viene modificato.

{ attributes, setAttributes }

Edit({ attributes, setAttributes })

Quando scrivi un blocco WordPress, la funzione Edit e la funzione save ricevono props, degli oggetti che WordPress passa automaticamente al blocco.

Uno di questi oggetti è:

{ attributes, setAttributes }

Sono due proprietà dell’oggetto props.

È equivalente a:

function Edit( props ) {
    const attributes = props.attributes;
    const setAttributes = props.setAttributes;
}

È solo destructuring JavaScript per prendere facilmente quei due valori.

attributes è un oggetto che contiene tutti gli attributi del blocco, definiti nel block.json.

Ti ricordi che abbiamo aggiunto minutes agli attributes nel file block.json all’inizio?

Questo significa che in Edit() troverai:

attributes.minutes

setAttributes() è una funzione fornita da Gutenberg che serve ad aggiornare gli attributi del blocco.

setAttributes({ minutes: newMinutes });

Aggiorna l’attributo minutes e avvisa l’editor che il blocco è cambiato.

È come usare setState in React.

File src/save.js

Siccome stiamo creando un blocco statico, dobbiamo sistemare come il plugin salva le informazioni quando aggiorni l’articolo.

Per farlo dobbiamo modificare il file save.js.

Inizialmente il file era:

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

export default function save() {
	return (
		<p { ...useBlockProps.save() }>
			{ 'Riaco Reading Time – hello from the saved content!' }
		</p>
	);
}

Ora dobbiamo modificare il codice in:

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

export default function save({ attributes }) {
	const { minutes } = attributes;

	return (
		<p { ...useBlockProps.save() }>⏱️ Reading time: {minutes} minutes</p>
	);
}

Vengono letti gli attributes passati alla funzione save().

Dagli attributes vengono estratti i minutes (i minuti calcolati nell’editor).

Poi come output viene ritornato un <p> tag con all’interno ⏱️ Reading time: {minutes} minutes dove al posto di {minutes} verranno mostrati il numero di minuti effettivi.

Questo è ciò che viene salvato nel contenuto dell’articolo, al posto del tuo blocco.

Il codice salvato nel database sarà:

<!-- wp:create-block/riaco-reading-time {"minutes":3} -->
<p class="wp-block-create-block-riaco-reading-time">⏱️ Reading time: 3 minutes</p>
<!-- /wp:create-block/riaco-reading-time -->

Quindi è salvato in maniera statica all’interno del contenuto dell’articolo stesso.

Risultato

Se vai a vedere l’articolo nel frontend dovresti vedere il tempo di lettura aggiornato.

reading time in frontend wordpress

Dal sorgente della pagina si vede che il risultato è proprio quello ceh ci aspettavamo:

<p class="wp-block-create-block-riaco-reading-time">⏱️ Reading time: 3 minutes</p>

Cambiare icona

Se vuoi cambiare icona del blocco puoi modificare il block.json, dove al posto di:

"icon": "smiley",

Dovrai inserire lo slug della dashicon che vuoi usare.

"icon": "clock",
icon changed in block wordpress

Oppure puoi inserire direttamente una icona <svg> all’interno del file index.js nella funzione registerBlockType:

registerBlockType(metadata.name, {
	icon: {
		src: (
			<svg
				xmlns="http://www.w3.org/2000/svg"
				width="24"
				height="24"
				viewBox="0 0 24 24"
				fill="none"
				stroke="currentColor"
				stroke-width="2"
				stroke-linecap="round"
				stroke-linejoin="round"
				class="lucide lucide-timer-icon lucide-timer"
			>
				<line x1="10" x2="14" y1="2" y2="2" />
				<line x1="12" x2="15" y1="14" y2="11" />
				<circle cx="12" cy="14" r="8" />
			</svg>
		),
	},

	edit: Edit,
	save,
});

In questo caso rimuovi l’icon dal block.json però.

Cambia lo stile del blocco

Come vedi, nell’editor e nel frontend il blocco è uno “stupendo” sfondo blu. Questo perché creando il plugin con create-block è stato aggiunto del css di prova nel file style.scss.

.wp-block-create-block-riaco-reading-time {
	background-color: #21759b;
	color: #fff;
	padding: 2px;
}

È possibile cambiare lo stile di base del blocco modificando qui il codice css.

È importante sapere che per gestire lo stile tramite css abbiamo 2 file:

  • style.scss: viene caricato sia nell’editor che nel frontend.
  • editor.scss: viene caricato solamente nell’editor, non nel frontend.

Approfondimenti

Ti consiglio di guardare anche:

Mostrare il tempo di lettura in un template

Il plugin è stato realizzato solo per capire come funziona meglio la creazione di un blocco statico.

Se hai bisogno di mostrare il tempo di lettura in un template, ad esempio nella pagina blog, allora dovrai convertire il blocco statico in un blocco dinamico.

Sponsor

Vhosting
themeforest