HTMX potrebbe essere un grosso problema per WordPress

Pubblicato: 2024-05-10

Costruire un'esperienza utente ricca nel browser può essere un compito impegnativo, che spesso richiede una quantità significativa di codice JavaScript. Man mano che crescono le esigenze e le ambizioni della nostra applicazione, aumenta anche la complessità del nostro codice JavaScript. Non sorprende quindi la frequenza con cui gli sviluppatori hanno rivisto il modo in cui pensiamo e scriviamo le app JavaScript.

Giorni dall'ultimo framework JS.

Gli sviluppatori di plugin per WordPress se la passano peggio. L'ambiente a cui ci rivolgiamo non è né un server che controlliamo, né uno con il controllo completo sull'intera pagina. Sebbene sia molto possibile utilizzare con successo un framework JavaScript in un plugin WordPress, può anche essere straordinariamente facile ritrovarsi con un progetto la cui scala e complessità vanno oltre ciò che intendevi o ti aspettavi.

E se non fosse necessario che andasse così? In questo articolo esploreremo il modo in cui le moderne interfacce utente Web vengono create con JavaScript, le difficoltà che gli sviluppatori devono affrontare e l'alternativa offerta da HTMX. In particolare, daremo un'occhiata al motivo per cui HTMX e WordPress potrebbero essere un'accoppiata perfetta.

Come siamo arrivati ​​qui

Prima di JavaScript, i browser erano fondamentalmente solo glorificati lettori di documenti. Pertanto, la maggior parte delle esperienze sul web erano "applicazioni multipagina", o AMP in breve. Gli MPA sono applicazioni Web costituite da più documenti HTML, uno per ogni pagina dell'applicazione. Man mano che l'utente utilizza l'applicazione, gli vengono mostrati diversi documenti con diverse azioni disponibili.

Le AMP sono molto semplici da costruire. La navigazione avviene utilizzando i tag <a> per collegarsi ad altri documenti e l'input dell'utente può essere acquisito con un elemento <form> . Il server risponde alle richieste di collegamento e modulo con nuovi documenti HTML, sostituendo la pagina visualizzata sullo schermo.

Un buon esempio di AMP con cui probabilmente hai molta familiarità è WP Admin. Ogni pagina di amministrazione è un documento con HTML generato dal codice PHP di WordPress in esecuzione sul server. La maggior parte delle pagine in WP Admin, come le pagine delle impostazioni di WordPress, tendono ad essere costituite principalmente da moduli che tu, l'utente, puoi inviare.

Al contrario, un'applicazione a pagina singola, o SPA, è un'applicazione che utilizza una singola pagina HTML. La navigazione e l'input dell'utente vengono quindi gestiti dal codice JavaScript, modificando dinamicamente parti della pagina sul posto senza la necessità di sostituire l'intera pagina o aggiornarla. Ciò si traduce in un'esperienza utente più fluida e reattiva.

Al giorno d'oggi, molte applicazioni web utilizzano SPA per la loro interfaccia web. In RebelCode, abbiamo creato SPA per le interfacce di amministrazione dei nostri due principali plugin WordPress: Spotlight e Aggregator. Anche l’editor del sito relativamente nuovo in WordPress è una SPA, così come l’editor dei post basato su blocchi.

Il prezzo che paghiamo

Le SPA sono applicazioni proprie, scritte in JavaScript e in esecuzione nel browser. La loro stessa definizione è anche il loro più grande avvertimento: non hanno accesso immediato alle risorse del server. Ciò significa che dobbiamo stabilire un canale di comunicazione tra la SPA e il server.

Creiamo un semplice plugin WordPress per usare un esempio. Questo plugin fornisce
una semplice interfaccia utente CRUD per la gestione dei libri. L'API interna del plugin sul server potrebbe assomigliare a questa:

 <?php function get_books(?int $count = null, int $page = 1): Book[]; function get_book(int $id): Book; function insert_book(Book $book): Book; function update_book(Book $book): Book; function delete_book(int $id): void;

Per creare la nostra moderna interfaccia SPA, utilizzeremo un framework JavaScript come React; il framework JavaScript più popolare utilizzato anche da WordPress. Iniziamo aggiungendo una pagina di amministrazione:

 <?php add_action('admin_menu', function () { add_menu_page('Books', 'Books', 'manage_options', 'books', 'books_page'); }); function books_page() { echo '<div></div>'; }

La nostra pagina eseguirà il rendering di un singolo elemento <div> vuoto che fungerà da radice della nostra applicazione React dove verrà eseguito il rendering del resto dell'interfaccia utente.

 const rootEl = document.getElementById("books-app"); const root = ReactDOM.createRoot(rootEl); root.render(<BooksApp />); function BooksApp() { return ( <div> <h1>My Books</h1> ... </div> ); }

Allora come elenchiamo i libri archiviati nel database? Il codice per farlo è sul server, quindi abbiamo bisogno di un modo per chiamarlo e ottenere il risultato.

Per fare ciò, possiamo esporre un'API JSON dal server. L'app React può quindi effettuare una richiesta all'URL della nostra API, ricevere i libri in formato JSON, quindi eseguire il rendering dell'elenco. Per questo esempio, supponiamo di aver aggiunto un endpoint all'API REST di WordPress:

 GET https://my-wp-site.com/wp-json/books { "books": [ { "id": 15, "title": "Mistborn", "author": "Brandon Sanderson", }, { "id": 44, "title": "The Hobbit", "author": "JRR Tolkien", }, ] }

Possiamo quindi scrivere un componente React che prelevi i libri e li visualizzi come un elenco:

 function BookList() { const [books, setBooks] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); useEffect( function () { setIsLoading(true); fetch("https://my-wp-site.com/wp-json/books") .then((res) => res.json()) .then((data) => setBooks(data.books)) .else((error) => setError(error)) .finally(() => setIsLoading(false)); }, [setBooks, setIsLoading], ); if (isLoading) { return <div>Loading...</div>; } if (error) { return <div>Error: {error}</div>; } return ( <ul> <li> {books.map((book) => ( <a key={book.id} href={book.url}> {book.title} </a> ))} </li> </ul> ); }

Ma questa soluzione è troppo ingenua e produce un'esperienza utente approssimativa. Non gestisce le modifiche di stato dopo lo smontaggio del componente, la memorizzazione nella cache della risposta, il nuovo tentativo di query non riuscite o impedisce allo stato obsoleto di sovrascrivere lo stato più recente. In effetti, il modo in cui utilizziamo fetch() in un effetto React è generalmente scoraggiato.

In molti modi, questo può essere peggiore di un AMP tradizionale. Quindi, per farlo correttamente, dovremo implementare alcune altre cose nel nostro client. Oppure, più realisticamente, utilizza pacchetti di terze parti.

Ma tutto questo comincia a sembrare uno sforzo sproporzionato solo per fornire un elenco di libri. Abbiamo davvero bisogno di creare un'app JavaScript e un'API JSON per creare un'esperienza utente fluida?

Mettiamo a confronto questo con un MPA, dove il rendering dell'elenco dei libri può essere realizzato in poche righe di codice PHP, senza alcuna dipendenza:

 <?php function render_books() { ?> <ul> <?php foreach (get_books() as $book): ?> <li> <a href="<?= $book->url ?>"> <?= $book->title ?> </a> </li> <?php endforeach; ?> </ul> <?php }

Ma ovviamente questo non è un confronto equo. Questo elenco di libri è solo HTML statico; non è reattivo ai cambiamenti di stato o all'input dell'utente.

Se vogliamo avere un'esperienza simile a una SPA e allo stesso tempo eseguire il rendering dell'HTML sul server, dove il nostro codice ha accesso immediato al database, dovremo trovare un modo per far sì che l'HTML renderizzato dal server raggiunga il browser e sostituire l'elenco precedente di libri. Ma raggiungere questo obiettivo senza alcun codice JavaScript è attualmente impossibile, quindi dovremmo stringere i denti e utilizzare comunque JavaScript.

Ma non abbiamo bisogno di scriverlo noi stessi.

Presentazione di HTMX

HTMX è una piccola libreria JavaScript che fa principalmente una cosa: consentire all'HTML di richiedere nuovo HTML dal server. Lo fa utilizzando nuovi attributi, che ci permettono di dire a HTMX da dove prendere il nuovo HTML, con cosa scambiarlo e cosa attiva lo scambio. Funziona come un ponte tra il nostro server HTML e la pagina nel browser.

Questo è un modo molto diverso di pensare alle SPA, poiché non stiamo creando un'applicazione JavaScript client per aggiornare la pagina corrente. Invece, aggiungiamo semplicemente alcuni attributi HTML per dire a HTMX come vogliamo che la pagina cambi quando si verificano determinati eventi.

Anche senza HTML è già possibile modificare ciò che viene mostrato sullo schermo utilizzando solo HTML, anche se in modo molto limitato. Hai già familiarità con questa funzionalità HTML: l'umile elemento link <a> .

 <a href="https://my-wp-site.com/books">View books</a>

Un elemento link fornisce al browser tutte le informazioni necessarie per effettuare la navigazione. Quando viene cliccato, il browser prende l' href dall'elemento, effettua una richiesta a quell'URL, scarica la risposta e, supponendo che contenga HTML, sostituisce il contenuto della pagina con il nuovo HTML.

L'elemento <form> è un altro esempio di come l'HTML può richiedere nuovo HTML.

 <form action="/contact.php"> <label> Your message: <input type="text" name="message" /> </label> <button type="submit">Send message</button> </form>

Questa volta, il browser raccoglie i valori da tutti gli input nel modulo, li invia al server, scarica la risposta e la visualizza sullo schermo.

Perché solo <a> e <form> dovrebbero essere in grado di effettuare richieste HTTP? Perché dovresti poter sostituire solo l' intero schermo?

Dal file leggimi GitHub di HTMX

Bene, HTMX cambia la situazione.

 <a href="https://my-wp-site.com/books" hx-target="#books"> View books </a> <div></div>

Con l'attributo HTMX hx-target , facendo clic sul collegamento verrà ora inserita la risposta da https://my-wp-site.com/books all'interno dell'elemento con l'ID "books" . Naturalmente, l'obiettivo qui non è incorporare una pagina all'interno di un'altra. Il nostro server non ha bisogno di rispondere con la pagina intera e può invece rispondere semplicemente con un frammento HTML.

Esponendo frammenti HTML dal nostro server e dicendo a HTMX come, da dove e quando ottenere tali frammenti, possiamo creare un'applicazione web simile a SPA senza JavaScript, dove il server ha il pieno controllo. In un certo senso, l'HTML è diventato il nostro nuovo JSON.

E tutto ciò che dobbiamo fare è caricare lo script HTMX nella nostra pagina:

 <script src="https://unpkg.com/[email protected]"></script>

(Assicurati di controllare la documentazione HTMX per istruzioni, poiché il codice sopra potrebbe non essere aggiornato).

Diamo un'occhiata a un altro esempio:

 <button hx-get="/button/off" hx-target="this" hx-swap="outerHTML"> Turn off </button>

C'è molto altro da fare qui, quindi analizziamolo:

  • hx-get specifica l'URL a cui inviare una richiesta GET quando si fa clic sul pulsante.
  • hx-target="this" dice a HTMX di scambiare il pulsante cliccato con la risposta.
  • hx-swap="outerHTML" dice a HTMX di scambiare l'intero pulsante, non solo quello che c'è al suo interno.

Nel complesso, questo dice a HTMX:

Quando si fa clic sul pulsante, inviare una richiesta GET a /button/off e sostituire questo pulsante con la risposta.

Supponiamo che il server risponda a /button/off con il seguente codice HTML:

 <button hx-get="/button/on" hx-target="this" hx-swap="outerHTML"> Turn on </button>

Riesci a vedere la differenza? L'attributo hx-get ora punta a /button/on e il testo all'interno del pulsante ora è "Attiva". Quando si fa clic su questo pulsante, verrà sostituito anche con la risposta di /button/on . Come puoi immaginare, possiamo fare in modo che il server risponda con il pulsante originale per completare la nostra commutazione!

Questa semplice idea di consentire a qualsiasi elemento di richiedere nuovo HTML dal server e decidere dove va a finire si rivela piuttosto potente. Possiamo creare schede, effettuare ricerche con risultati in tempo reale, barre di avanzamento e altro ancora.

Pro e contro

A differenza della maggior parte dei framework JavaScript, HTMX non richiede la compilazione e il raggruppamento del codice dell'applicazione client. Questo da solo è un enorme vantaggio; I sistemi di compilazione JavaScript possono essere notoriamente difficili da configurare e mantenere, soprattutto quando si iniziano a introdurre funzionalità e librerie più esotiche, come TypeScript, JSX, preprocessori CSS, ecc. Non è raro che team di dimensioni medio-grandi abbiano uno o più membri dedicati a questo compito.

Un altro vantaggio evidente è la mancanza di un'applicazione client separata. Poiché tutto ciò di cui abbiamo bisogno è un server HTTP che risponda in HTML, possiamo utilizzare qualsiasi linguaggio di programmazione che preferiamo. Questo potrebbe essere un grande punto di forza per te se il tuo team non ha familiarità con JavaScript moderno o non è abbastanza grande da giustificare la creazione di due applicazioni. Può essere particolarmente allettante se sei uno sviluppatore di plugin WordPress, poiché potresti utilizzare PHP per tutti gli aspetti del tuo plugin.

Ma forse il vantaggio più importante è che non avrai più bisogno di un’API tra il back-end e il front-end della tua applicazione. Ciò può far risparmiare un'enorme quantità di tempo di sviluppo, oltre a ridurre la quantità di codice che può produrre bug, il che consente anche di risparmiare tempo a lungo termine.

Tuttavia, non dovremmo essere così ingenui da presumere che usare HTMX significhi non dover scrivere JavaScript . Potrebbe essere ancora necessaria una certa quantità di JavaScript per operazioni come il trascinamento della selezione, i grafici, i selettori di colori e date e così via. Sebbene possiamo sempre utilizzare soluzioni indipendenti dal framework, come SortableJS e Floating UI. Inoltre, in futuro potremmo anche riscontrare una minore necessità di JavaScript poiché gli standard web continuano ad evolversi con nuovi elementi HTML, come il recente elemento <dialog> .

In secondo luogo, PHP, per ironia della sorte, non è molto bravo con i modelli HTML, nonostante sia stato creato per fare proprio questo. La sintassi dei tag è eccessivamente dettagliata e la sintassi delle stringhe HEREDOC ha un supporto limitato per l'interpolazione delle stringhe.

Infine, creare un endpoint in WordPress non è molto semplice. Considera il plug-in dei libri degli esempi precedenti. Dobbiamo avere un percorso sul server che risponda con l'elenco dei libri in formato HTML. Come registriamo questo endpoint?

  • Rileva un parametro GET durante l'azione init o admin_init ?
  • Utilizzare l'API Admin Ajax?
  • Registrare un endpoint API REST?
  • Aggiungere una regola di riscrittura personalizzata?

Ci sono molte opzioni, ma nessuna lo rende così semplice come dovrebbe essere.

HATEOAS

C'è un sottile dettaglio nel nostro esempio precedente che è molto facile non notare e che probabilmente sembrerà ovvio una volta sottolineato.

Quando riceviamo l'HTML dal server, il pulsante sulla pagina è la variante ON o la variante OFF. A seconda di quello mostrato sullo schermo, l'azione del clic sarà diversa.

Per questo motivo non è necessario che il browser comprenda la nostra applicazione. Normalmente faremmo capire al browser fornendo il codice JavaScript per programmare esplicitamente tutti i comportamenti. Ora abbiamo solo HTML e il browser non necessita di alcuna conoscenza preliminare di come si comporta la nostra applicazione o quale sia il suo stato. Deve solo eseguire il rendering dell'HTML sullo schermo, che a sua volta codifica lo stato della nostra applicazione.

Questo tipo di architettura è nota come HATEOAS, che sta per "Hypermedia As The Engine Of Application State". È un tipo specializzato di architettura REST che utilizza l'ipermedia come mezzo per il trasferimento dello stato e lo stesso ipermedia diventa l'interfaccia attraverso la quale l'utente guida l'applicazione in nuovi stati.

Il sito web HTMX ha una vasta raccolta di articoli, saggi e discorsi su questo argomento, se sei interessato a saperne di più. Ai fini di questo articolo, passiamo al motivo per cui HTMX potrebbe essere un grosso problema per gli sviluppatori WordPress.

HTML <3 WordPress

WordPress è un server PHP gigante e monolitico. Anche i plugin di WordPress sono scritti principalmente in PHP. Possono aggiungere nuove funzionalità al sito utilizzando le API PHP fornite da WordPress, come l'API Hooks e l'API Database. Queste API non sono disponibili da JavaScript, quindi gli sviluppatori di plugin dovrebbero voler mantenere la maggior parte possibile del codice del plugin sul server. Se mai c'è stata una motivazione per utilizzare HTMX, è proprio questa!

In molti modi, HTMX è stato creato per WordPress. O meglio, per applicazioni come WordPress; applicazioni che preferirebbero non essere gravate da una lingua straniera che le costringe a lasciarsi alle spalle le raccolte di API del server. Soprattutto non quando sarebbe sufficiente il semplice trasferimento dello stato utilizzando l’ipermedia.

Semplificare la creazione di buone interfacce utente per i plugin WordPress può avere un impatto drammatico sull’ecosistema dei plugin. Gli sviluppatori che mantengono plug-in gratuiti potrebbero ritenere più fattibile creare esperienze utente migliori per i propri utenti e i team più piccoli potrebbero essere in grado di eseguire l'iterazione più velocemente delle funzionalità risparmiando tempo. Ciò può aiutare a rendere i plugin più piccoli più competitivi in ​​un mercato fortemente dominato da grandi team con budget ancora più grandi.

Anche i plugin più grandi potrebbero essere particolarmente interessati. Le app JavaScript possono crescere in modo esponenziale e veloce. HTMX potrebbe consentire a questi plugin di rimuovere le loro enormi API JSON e app JavaScript e lasciare al loro posto un server HTML snello che abbia pieno accesso alle API di WordPress.

Pensieri finali

Sto giocando con HTMX ormai da un po', usandolo con PHP e Go. Offre un'alternativa convincente per la creazione di interfacce utente sul Web e un argomento convincente per l'utilizzo dell'ipermedia per guidare lo stato dell'applicazione.

Se sei uno sviluppatore di plugin, assicurati di dare un'occhiata a HTMX. Abbiamo appena scalfito la superficie in questo articolo e la documentazione è scritta molto bene con numerosi esempi. È anche sorprendentemente breve, considerando quanto HTMX viene fornito immediatamente. Dovresti essere in grado di iniziare con HTMX e PHP in pochi minuti.