KuroCMS DevLog Vol.5: Implementazione del tipo Ricetta
Abbiamo implementato una nuova funzione scheda ricetta in KuroCMS in base al feedback. Scoprite l'architettura, la generazione JSON-LD e l'integrazione dell'editor.
In "KuroCMS" e "KuroEditor", sviluppati come CMS headless di nuova generazione funzionante sul edge, è stata ufficialmente implementata una nuova "scheda ricetta" nell'ultima versione. Mentre le versioni precedenti di KuroCMS si concentravano sull'espressione generale dei documenti utilizzando markdown e HTML standard, l'introduzione di questa scheda ricetta consente una gestione rigorosa di metadati come tempi di cottura, liste di ingredienti, porzioni e passaggi, garantendo un output coerente sotto forma di dati strutturati che i motori di ricerca come Google possono facilmente comprendere (Schema.org Recipe). In questo articolo, dettagliamo il design tecnico di questa scheda ricetta e mostriamo come viene applicata la validazione sui layer dell'editor, delle API e del frontend.
Filosofia di design e base: Modello di dati intelligente limitato a 1 documento = 1 ricetta
Nell'implementare la scheda ricetta, la sfida più grande che il team di sviluppo ha affrontato è stata "la coerenza dei dati e l'eliminazione della ridondanza". Mentre i siti di ricette generali hanno spesso diverse schede ricetta sparse in un singolo articolo, questo tende a generare una struttura rotta dal punto di vista dei dati strutturati dei motori di ricerca (JSON-LD). Se più piatti o passaggi diversi vengono visualizzati in parallelo per un singolo URL (articolo), la corrispondenza tra le proprietà comuni (come il nome del piatto, l'immagine finita, la descrizione e la data di pubblicazione) e le schede ricetta individuali diventa ambigua.
Pertanto, KuroCMS impone un vincolo di "1 documento = 1 ricetta". La RecipeCard è responsabile solo delle "parti variabili specifiche della ricetta" (porzioni, tempo di cottura, ingredienti e passaggi), mentre le informazioni comuni come il nome del piatto, la descrizione, l'image finita e la data di pubblicazione vengono riutilizzate dalle proprietà del documento (titolo, sommario, immagine di copertina, data di creazione, ecc.). Questo evita inserimenti ridondanti e previene problemi in cui nomi di ricette identici si ripetono in un formato rotto all'interno dello stesso dato strutturato.
Onestamente, dal punto di vista del design di KuroEditor, non volevamo accettare la restrizione di 1 documento = 1 ricetta, in quanto limita la flessibilità del layout. Tuttavia, poiché le pagine di ricette degli utenti ottengono valutazioni SEO più elevate e sono più facili da leggere e referenziare, applichiamo rigorosamente la regola di una sola scheda ricetta per articolo nella versione attuale.
Garanzia di coerenza tramite funzioni pure condivise
In un CMS headless, eseguire una validazione di struttura identica sull'editor avanzato (KuroEditor), sulle API di salvataggio e sul processo di build statico delle pagine pubbliche non è facile. Se scrivete la logica di validazione separatamente utilizzando linguaggi o framework diversi per ogni livello, le differenze di implementazione causeranno inevitabilmente problemi, come "salvato nell'editor ma fallito sul server API", o "salvato nel database ma fallito nella build statica del frontend, rompendo il sito web".
Per risolvere questo problema fondamentalmente, KuroCMS ha adottato un modello di progettazione di "funzione pura condivisa" (Shared Pure Function). Nello specifico, integriamo "dist/kuro-recipe.js" (costruito nel repository a monte di KuroEditor) nel cuore di KuroCMS come "src/kuro-recipe.js", insieme al file di definizione di tipo "kuro-recipe.d.ts". Ciò garantisce che lo stesso codice JavaScript ispezioni i dati della ricetta nel corpo HTML durante l'editing, le chiamate API di salvataggio e le build statiche. Questo design a fonte unica di verità (Single Source of Truth) minimizza gli errori.
*Poiché sia KuroEditor che KuroCMS sono "software open-source" sviluppati da Kuroboo, consultare la cronologia di GitHub faciliterà la comprensione.
Validazione rigorosa nelle API di salvataggio: Specifiche di recipe-guard.ts
Quando si salva (PUT) un articolo in KuroCMS, l'API del lato server non si limita a memorizzare la stringa. Ispeziona rigorosamente se i dati della ricetta sono correttamente integrati nel corpo HTML inviato. Questo ruolo è svolto dalla funzione "checkRecipeCards(bodyHtml, isRecipeType)" in "src/recipe-guard.ts" nel backend.
L'aspetto più critico di questa validazione è la tempistica. KuroCMS considera l'editing collaborativo multiutente, e i dati finali salvati sono scritti nel database dopo una "fusione a 3 vie" (3-way merge) di diverse versioni. Se la validazione viene eseguita prima della fusione, non possiamo evitare casi in cui la fusione duplica accidentalmente le schede ricetta o inserisce dati rotti. Pertanto, il controllo viene eseguito sempre sul testo finale dopo la fusione. Se la validazione fallisce, l'API restituisce un errore chiaro al client, bloccando il processo di salvataggio.
| Elemento di ispezione | Dettagli e misure di sicurezza |
|---|---|
| Numero di schede | Confermate che esiste esattamente 1 scheda in un articolo ricetta, ed esattamente 0 schede negli articoli non-ricetta. |
| Decodifica di data-recipe | Decodificate i dati JSON ricetta codificati e integrati nel tag HTML e verificate se sono conformi allo schema. |
| Allowlist di attributi | Verificate rigorosamente gli attributi HTML sconosciuti. Questo elimina le vulnerabilità in cui utenti maliziosi iniettano script XSS come "onclick" attraverso il testo del corpo HTML. |
| Verifica della versione | Verificate la compatibilità di versione dello schema ricetta per evitare di salvare vecchie versioni di schede o formati corrotti. |
Output JSON-LD: Generazione automatica della struttura Recipe per la SEO
Questo è il valore fondamentale dell'aggiunta della scheda ricetta. Normalmente, KuroCMS genera "Article" come dati strutturati per la pagina, ma quando un documento contiene una scheda ricetta, la sostituisce automaticamente e genera "Recipe" come dati strutturati principali.
Legge l'attributo "data-recipe" dal HTML salvato e trasmette i dati analizzati sotto le variabili "article.recipe" e "page.isRecipe" al modello HTML. Per evitare "il controllo di tipo per confronto di stringhe" nel modello, utilizza un semplice ramo booleano (#if page.isRecipe) per cambiare modello. I dati temporali vengono convertiti automaticamente internamente al formato internazionale ISO-8601 duration (ad esempio, "PT25M" per 25 minuti). Poiché la visualizzazione HTML e i dati strutturati JSON-LD sono generati a partire dalla stessa identica fonte di dati unica, non esiste rischio di informazioni errate per i motori di ricerca.
Integrazione di amministrazione: Logica di ricreazione dinamica dell'editor
La logica di integrazione è stata incorporata anche nell'area di modifica del pannello di amministrazione. In KuroEditor, l'attivazione o la disattivazione del "pulsante Pentola" per la creazione di ricette è controllata dall'opzione "recipeUi" passata all'inizializzazione. Dato che il comportamento predefinito di KuroEditor è mostrare il pulsante (true), KuroCMS non ha bisogno di specificarlo normalmente, ma se impostato su false, appare immutato per gli utenti che non utilizzano KuroEditor per l'editing delle ricette, riducendo al minimo l'impatto della modifica.
Inoltre, a livello di KuroEditor, le schede ricetta sono ora bloccate a 1 ricetta per articolo (il secondo pulsante è disattivato e non può essere cliccato). Questo preserva la regola principale degli articoli di ricette. KuroCMS esegue anche un doppio controllo al salvataggio per assicurarsi che i controlli specifici per le ricette vengano eseguiti correttamente per gli articoli ricetta.
Su questa base, è stata aggiunta una suite di test correlata alle ricette "npm run test:recipe" (src/recipe-guard.test.ts, 12 casi di test in totale), che valida tutto, dal numero di schede all'escape di caratteri negli attributi.
Problemi rimanenti e roadmap futura
Con questo aggiornamento, il "sistema centrale" dell'articolo ricetta e la "validazione di salvataggio" sono completamente operativi. Tuttavia, KuroCMS non offre ancora un layout di pagina ricetta completo come i grandi portali. Il nostro obiettivo era consentire la pubblicazione facile di ricette su siti web personali, generando automaticamente dati SEO senza che l'utente debba scriverli. Ora chiunque può facilmente lanciare un sito di cucina.
Inoltre, poiché KuroCMS ha un sistema di modelli, gli utenti possono continuare a rifinire il design da soli (vedere la Fonte 3 per maggiori dettagli). Per rendere KuroCMS ancora più facile da usare, il team di sviluppo continuerà a implementare aggiornamenti basati sui vostri feedback, quindi grazie per il vostro supporto!