Il template blog di EmDash fornisce un sito Astro funzionante con articoli, pagine, autori, categorie, tag, ricerca, commenti, widget e un feed RSS. Questo tutorial crea la versione Cloudflare, pubblica un articolo e traccia quell’articolo attraverso il codice del template.
Prerequisiti
Installa Node.js 22.12 o successivo e pnpm prima di iniziare.
Hai bisogno di un account Cloudflare solo quando fai il deploy del sito. Durante lo sviluppo locale, il template esegue versioni locali del database e dello storage file sul tuo computer.
Creare la struttura del blog
Il seguente comando crea my-blog dal template blog Cloudflare e installa le sue dipendenze con pnpm:
npm create emdash@latest my-blog -- --template cloudflare:blog --pm pnpm --yes
Lo scaffolder crea anche un file .env locale con un EMDASH_ENCRYPTION_KEY. Il .gitignore generato esclude .env dal controllo versione. Se il comando segnala che l’installazione delle dipendenze è fallita, entra nella directory del progetto ed esegui pnpm install prima di continuare.
Avvia il server di sviluppo locale:
cd my-blog
pnpm dev
Apri l’URL locale stampato nel terminale, poi apri /_emdash/admin. Completa la schermata di setup se è la prima esecuzione. I dati seed del template creano il modello di contenuto e il contenuto di esempio durante il setup.
Comprendere il modello di contenuto
Il template definisce due collezioni in seed/seed.json:
postsabilita bozze, revisioni, ricerca e SEO tramitesupports, e abilita i commenti separatamente concommentsEnabled: true;pagessupporta bozze, revisioni e ricerca.
Ogni articolo ha questi campi personalizzati:
| Campo | Scopo |
|---|---|
title | Titolo dell’articolo obbligatorio |
featured_image | Immagine opzionale mostrata con l’articolo |
content | Corpo in Portable Text |
excerpt | Testo breve usato nelle liste articoli e nei fallback dei metadati |
EmDash aggiunge campi di sistema come l’ID contenuto stabile, slug, stato, tempi di creazione e aggiornamento e tempo di pubblicazione. Il template definisce anche tassonomie category e tag per gli articoli, più firme che possono accreditare uno o più autori.
Il server di dev genera emdash-env.d.ts da questo schema. Di conseguenza, getEmDashCollection("posts") restituisce voci la cui proprietà data è tipizzata come Post.
Pubblicare il primo articolo
-
Nella barra laterale dell’admin, seleziona Posts, poi Add New.
-
Inserisci un titolo. EmDash suggerisce uno slug dal titolo; modificalo se l’URL pubblica necessita un valore diverso.
-
Aggiungi un estratto e scrivi il corpo nell’editor Content.
-
Seleziona un’immagine in evidenza dalla Media Library o caricane una. Aggiungi testo alternativo che descriva lo scopo dell’immagine nell’articolo.
-
Assegna una firma, una categoria e i tag pertinenti nel pannello impostazioni.
-
Seleziona Save. La voce diventa una bozza e l’editor apre il suo URL permanente.
-
Seleziona Preview e controlla la pagina dell’articolo. Torna all’editor e seleziona Publish quando la bozza è pronta.
Apri /posts/your-post-slug sul sito locale. L’articolo appare anche nella home page e nell’archivio articoli. Se non appare, conferma che l’editor mostra Published, non Draft o Scheduled.
Dopo la pubblicazione, le modifiche si salvano automaticamente in una nuova bozza mentre l’articolo corrente rimane online. Seleziona Publish changes quando la bozza rivista deve sostituirlo. La guida alla creazione di contenuti spiega anteprime, programmazione, revisioni e blocchi di modifica.
Seguire la query della collezione
La home page e l’archivio articoli chiamano getEmDashCollection() durante il render del server. Il template ordina gli articoli nel database per il campo published_at:
---
import { getEmDashCollection, getTermsForEntries } from "emdash";
const { entries: posts, cacheHint } = await getEmDashCollection("posts", {
orderBy: { published_at: "desc" },
});
if (Astro.cache?.enabled) Astro.cache.set(cacheHint);
const tagsByEntry = await getTermsForEntries(
"posts",
posts.map((post) => post.data.id),
"tag",
);
---
La query della collezione restituisce le voci pubblicate per default. Usa published_at, il nome del campo del database, per l’ordinamento. La proprietà publishedAt restituita è un Date JavaScript per il rendering.
L’helper di tassonomia riceve post.data.id perché le assegnazioni di tassonomia appartengono all’ID contenuto stabile. I link usano post.id invece, perché quello è lo slug orientato all’URL prodotto dal content loader:
<a href={`/posts/${post.id}`}>
<h2>{post.data.title}</h2>
{post.data.excerpt && <p>{post.data.excerpt}</p>}
</a>
Il template corrente raggruppa le ricerche dei tag con getTermsForEntries() invece di interrogare una volta per ogni articolo. Le firme sono già incluse in post.data.bylines dalla query della collezione.
Seguire la query dell’articolo
La route dinamica dell’articolo legge lo slug dall’URL e chiama getEmDashEntry(). L’estratto seguente mostra la query essenziale e il percorso di rendering, mentre il template completo gestisce anche SEO, firme, commenti, articoli correlati e widget:
---
import { decodeSlug, getEmDashEntry } from "emdash";
import { Image, PortableText } from "emdash/ui";
const slug = decodeSlug(Astro.params.slug);
if (!slug) return Astro.redirect("/404");
const { entry: post, error, cacheHint } = await getEmDashEntry("posts", slug);
if (error) return new Response("Unable to load post", { status: 500 });
if (!post) return Astro.redirect("/404");
if (Astro.cache?.enabled) Astro.cache.set(cacheHint);
---
<article>
{post.data.featured_image && <Image image={post.data.featured_image} priority />}
<h1>{post.data.title}</h1>
<PortableText value={post.data.content} />
</article>
Image legge il valore media selezionato dall’editor e genera output responsive. PortableText trasforma i dati di blocco memorizzati in intestazioni, paragrafi, link, immagini, blocchi di codice e gli altri tipi di blocco supportati.
Entrambi i template blog impostano output: "server" in astro.config.mjs. Queste query vengono eseguite quando una richiesta viene renderizzata, quindi il contenuto pubblicato non dipende da una lista di route statiche creata durante il build.
Usare categorie e tag
Il template include route di archivio per ogni categoria e tag. Una route di categoria prima risolve lo slug del termine, poi filtra gli articoli per quella tassonomia:
---
import { decodeSlug, getEmDashCollection, getTerm } from "emdash";
const slug = decodeSlug(Astro.params.slug);
const category = slug
? await getTerm("category", slug, { includeCounts: false })
: null;
if (!category) return Astro.redirect("/404");
const { entries: posts, error } = await getEmDashCollection("posts", {
where: { category: category.slug },
orderBy: { published_at: "desc" },
});
if (error) return new Response("Unable to load posts", { status: 500 });
---
La route tag usa lo stesso pattern con getTerm("tag", slug) e where: { tag: term.slug }. I redattori gestiscono termini e assegnazioni nell’admin; la guida alle Tassonomie copre categorie gerarchiche, tag piatti e tassonomie personalizzate.
getEmDashEntry() include i termini assegnati dell’articolo, quindi la route di dettaglio può renderizzarli senza un’altra query:
---
const categories = post.data.terms?.category ?? [];
const tags = post.data.terms?.tag ?? [];
---
{categories.map((category) => (
<a href={`/category/${category.slug}`}>{category.label}</a>
))}
{tags.map((tag) => (
<a href={`/tag/${tag.slug}`}>{tag.label}</a>
))}
Aggiungere la paginazione all’archivio
L’archivio articoli del template renderizza ogni articolo pubblicato. Quando l’archivio cresce, aggiungi un limit e usa la paginazione per offset per route numerate come /posts/page/2, o la paginazione per cursore per un link Articoli precedenti. Mantieni orderBy: { published_at: "desc" } invariato tra le pagine affinché le voci non cambino ordine inaspettatamente.
Gli esempi di paginazione mostrano entrambi gli approcci e spiegano quando scegliere ciascuno.
Controllare il feed RSS
Il template serve già /rss.xml. Il suo endpoint legge i 20 articoli più recenti con getEmDashCollection(), formatta ogni data di pubblicazione e esegue l’escape del titolo e dell’estratto prima di inserirli nell’XML. Legge anche il titolo del sito e il sottotitolo dalle impostazioni EmDash.
Dopo aver pubblicato l’articolo di prova, apri /rss.xml e cerca il suo titolo. Se il sito userà un URL di produzione assoluto nei feed, imposta l’opzione site di Astro prima del deployment; l’endpoint ricade sull’origine della richiesta corrente durante lo sviluppo locale.
A questo punto il blog ha un workflow di authoring, pagine articoli a runtime, archivi per tassonomia, rendering dei media e un feed. Continua con Interrogare il Contenuto per filtri e paginazione, o Libreria Media per l’editing degli asset e il tracciamento dell’uso. Per redigere o modificare articoli con un assistente IA, segui Strumenti IA.