
Installazione di WordPress/Bedrock + Astro
By
Ho deciso di testare questa configurazione: backend realizzato da WordPress con la struttura di Bedrock, tema per il frontend Astro. Qualche settimana fa avevamo visto come installare il tema Sage sempre di Roots (gli sviluppatori di Bedrock) e rimanere quindi in un ambiente PHP.
Adesso, con l’adozione di Astro come tema frontend, usciamo dal PHP ed entriamo in ReactJS (solo per il frontend) rendendo WordPress, come si dice in questi casi, headless, proprio senza testa…
Poiché Astro comunicherà con WordPress tramite API, consiglio di installarli su 2 domini distinti, per esempio così:
- dominio.com -> Astro
- cms.dominio.com -> WordPress
Il motivo è che hanno esigenze diverse (Astro non necessita di PHP o database, mentre WordPress sì) useranno quindi motori e “benzine” diverse. In questo modo avremo 2 mondi distinti che dialogano tramite il protocollo di internet in modo sereno e pulito.
WordPress Bedrock
Per l’installazione di un nuovo WordPress con la struttura data da Bedrock, segui le istruzioni già fornite nell’articolo citato sopra.
La scelta di usare questa struttura modificata di WordPress è legata al fatto che con Bedrock si rende ibrido WordPress per avvicinarlo a Laravel. Chi è un po’ navigato nello sviluppo web non può non aver mai incontrato Laravel sulla sua strada, essendo un framework famosissimo e potentissimo, famoso per la sua velocità, sicurezza e struttura ingegneristica avanzata.
Quindi è come trasformare WordPress e renderlo veloce e potente come Laravel, ma al contempo è come rendere Laravel più user friendly come WordPress…
Astro
Adesso installiamo Astro che ovviamente necessita di un server JS come NodeJS. Portiamoci nella console del sito da installare e digitiamo
mkdir astro cd astro npm init --yes npm install astro@latest
Oltre allo scheletro di Astro abbiamo bisogno di React per le pagine e Tailwind per il CSS e le aggiungiamo con i seguenti comandi
npx astro add react npx astro add tailwind
DocumentRoot
Sia per WordPress (solo per la versione Bedrock) sia per Astro, dobbiamo definire la DocumentRoot del sito su valori specifici diversi dalla cartella root di default /.
Per WordPress andrà impostata
NOME_CARTELLA_INSTALLAZIONE_DI_WORDPRESS/web
mentre per Astro
NOME_CARTELLA_DI_INSTALLAZIONE_DI_ASTRO/dist
Comunicazione tra Astro e WordPress
WordPress normalmente espone già degli endpoint che serviranno ad Astro per visualizzare le pagine ed il resto del sito. Per verificare se questi endpoint stanno effettivamente funzionando prova nella console a lanciare:
curl 'https://cms.dominio.com/wp-json/wp/v2/pages'
Essendo una semplice operazione di lettura (quindi dati pubblici) non è richiesta l’autenticazione, perciò dovresti vedere un array JSON con le prime pagine presenti su WordPress.
“Chi siamo”
Come esempio creiamo su WordPress una nuova pagina e chiamiamola “Chi siamo”.
Inseriamo un contenuto e pubblichiamola.
In Astro dobbiamo aggiungere al file .env la variabile che indica l’URL di WordPress (se il file non esiste creiamolo nella root del progetto Astro)
WORDPRESS=https://cms.domain.com
Creiamo 2 cartelle
mkdir -p src/lib mkdir -p src/pages
Aggiungiamo il file wordpress.ts dentro la cartella src/lib con questo contenuto
const WORDPRESS_URL = import.meta.env.WORDPRESS_URL;
if (!WORDPRESS_URL) {
throw new Error("La variabile WORDPRESS_URL non è configurata");
}
export interface WordPressRenderedField {
rendered: string;
}
export interface WordPressPage {
id: number;
date: string;
modified: string;
slug: string;
link: string;
title: WordPressRenderedField;
content: WordPressRenderedField;
excerpt: WordPressRenderedField;
featured_media: number;
}
async function wordpressFetch<T>(
endpoint: string,
parameters: Record<string, string> = {},
): Promise<T> {
const url = new URL(
`/wp-json/wp/v2/${endpoint.replace(/^\/+/, "")}`,
WORDPRESS_URL,
);
for (const [key, value] of Object.entries(parameters)) {
url.searchParams.set(key, value);
}
const response = await fetch(url);
if (!response.ok) {
throw new Error(
`Errore WordPress API: ${response.status} ${response.statusText}`,
);
}
return response.json() as Promise<T>;
}
export function getPages(): Promise<WordPressPage[]> {
return wordpressFetch<WordPressPage[]>("pages", {
status: "publish",
per_page: "100",
});
}
export async function getPageBySlug(
slug: string,
): Promise<WordPressPage | null> {
const pages = await wordpressFetch<WordPressPage[]>("pages", {
slug,
status: "publish",
});
return pages[0] ?? null;
}Creiamo un file dentro src/pages il cui nome ha questa struttura: [slug].astro, quindi la pagina che abbiamo creato prima sarà raggiungibile se il file lo chiameremo chi-siamo.astro, il cui contenuto dovrà essere (a scopo di test)
---
import { getPageBySlug } from "../lib/wordpress";
const page = await getPageBySlug("chi-siamo");
if (!page) {
throw new Error(
'Pagina WordPress con slug "chi-siamo" non trovata. Creala e pubblicala nel CMS.'
);
}
---
<html lang="it">
<head>
<title>{page.title.rendered}</title>
<meta
name="description"
content={page.excerpt?.rendered?.replace(/<[^>]*>/g, "") ?? ""}
/>
</head>
<body>
<h1 set:html={page.title.rendered} />
<main set:html={page.content.rendered} />
</body>
</html>Compiliamo tutti i file TS e CSS con npm run build
Rendiamo WordPress headless
La via più comoda è installare questo plugin: Headless Mode.
Poi dobbiamo impostare una variabile nel file .env (wp-config.php per una installazione standard di WordPress):
// Per WordPress/Bedrock // .env HEADLESS_MODE_CLIENT_URL='https://domain.com' // Per WordPress standard // wp-config.php define( 'HEADLESS_MODE_CLIENT_URL', 'https://domain.com' );
In questo modo se un utente per sbaglio inserisse lo slug sul dominio di WordPress verrebbe reindirizzata sul dominio di Astro.