Opzionale: Crea una raccolta di contenuti
Ora che hai un blog che utilizza il routing basato su file integrato di Astro, lo aggiornerai per usare una raccolta di contenuti (EN). Le raccolte di contenuti sono un modo potente per gestire gruppi di contenuti simili, come articoli di blog.
Preparati a…
- Sposta la tua cartella di articoli del blog in
src/blog/
- Crea uno schema per definire il frontmatter del tuo articolo del blog
- Usa
getCollection()
per ottenere contenuto e metadata degli articoli del blog
Impara: Pagine vs Raccolte
Sezione intitolata Impara: Pagine vs RaccolteAnche quando usi raccolte di contenuti, userai comunque la cartella src/pages/
per singole pagine, come la tua pagina Su di me. Ma, spostare i tuoi articoli del blog fuori da questa cartella speciale ti permetterà di usare API più potenti e performanti per generare il tuo indice di articoli del blog e visualizzare i tuoi singoli articoli del blog.
Allo stesso tempo, riceverai una guida e un autocompletamento migliori nel tuo editor di codice perché avrai uno schema (EN) per definire una struttura comune per ogni articolo che Astro ti aiuterà a far rispettare attraverso Zod, una libreria di dichiarazione e validazione di schemi per TypeScript. Nel tuo schema, puoi specificare quando le proprietà frontmatter sono richieste, come una descrizione o un autore, e quale tipo di dati ogni proprietà deve essere, come una stringa o un array. Questo porta a individuare molti errori prima, con messaggi di errore descrittivi che ti dicono esattamente qual è il problema.
Leggi di più sulle raccolte di contenuti di Astro (EN) nella nostra guida, o inizia con le istruzioni qui sotto per convertire un blog base da src/pages/posts/
a src/blog/
.
Metti alla prova le tue conoscenze
Sezione intitolata Metti alla prova le tue conoscenze-
Quale tipo di pagina probabilmente manterresti in
src/pages/
? -
Quale non è un vantaggio dello spostamento di articoli del blog in una raccolta di contenuti?
-
Le raccolte di contenuti usano TypeScript …
I passaggi seguenti mostrano come estendere il prodotto finale del tutorial Crea un Blog creando una raccolta di contenuti per gli articoli del blog.
Aggiorna le dipendenze
Sezione intitolata Aggiorna le dipendenzeAggiorna all’ultima versione di Astro e aggiorna tutte le integrazioni alle loro ultime versioni eseguendo i seguenti comandi nel tuo terminale:
# Aggiorna Astro e le integrazioni ufficiali insiemenpx @astrojs/upgrade
# Aggiorna Astro e le integrazioni ufficiali insiemepnpm dlx @astrojs/upgrade
# Aggiorna Astro e le integrazioni ufficiali insiemeyarn dlx @astrojs/upgrade
Crea una raccolta per i tuoi articoli
Sezione intitolata Crea una raccolta per i tuoi articoli-
Crea una nuova raccolta (cartella) chiamata
src/blog/
. -
Sposta tutti i tuoi articoli del blog esistenti (file
.md
) dasrc/pages/posts/
in questa nuova raccolta. -
Crea un file
src/content.config.ts
per definire uno schema (EN) per la tuapostsCollection
. Per il codice del tutorial del blog esistente, aggiungi i seguenti contenuti al file per definire tutte le proprietà frontmatter usate nei suoi articoli del blog:src/content.config.ts // Importa il glob loaderimport { glob } from "astro/loaders";// Importa utilità da `astro:content`import { z, defineCollection } from "astro:content";// Definisci un `loader` e uno `schema` per ogni raccoltaconst blog = defineCollection({loader: glob({ pattern: '**/[^_]*.md', base: "./src/blog" }),schema: z.object({title: z.string(),pubDate: z.date(),description: z.string(),author: z.string(),image: z.object({url: z.string(),alt: z.string()}),tags: z.array(z.string())})});// Esporta un singolo oggetto `collections` per registrare le tue raccolteexport const collections = { blog }; -
Affinché Astro riconosca il tuo schema, esci (
CTRL + C
) e riavvia il server di sviluppo per continuare con il tutorial. Questo definirà il moduloastro:content
.
Genera pagine da una raccolta
Sezione intitolata Genera pagine da una raccolta-
Crea un file pagina chiamato
src/pages/posts/[...slug].astro
. I tuoi file Markdown e MDX non diventano più automaticamente pagine usando il routing basato su file di Astro quando si trovano all’interno di una raccolta, quindi devi creare una pagina responsabile della generazione di ogni singolo articolo del blog. -
Aggiungi il seguente codice per interrogare la tua raccolta (EN) per rendere disponibili lo slug e il contenuto della pagina di ogni articolo del blog a ogni pagina che genererà:
src/pages/posts/[...slug].astro ---import { getCollection, render } from 'astro:content';export async function getStaticPaths() {const posts = await getCollection('blog');return posts.map(post => ({params: { slug: post.id }, props: { post },}));}const { post } = Astro.props;const { Content } = await render(post);--- -
Renderizza il tuo
<Content />
dell’articolo all’interno del layout per pagine Markdown. Questo ti permette di specificare un layout comune per tutti i tuoi articoli.src/pages/posts/[...slug].astro ---import { getCollection, render } from 'astro:content';import MarkdownPostLayout from '../../layouts/MarkdownPostLayout.astro';export async function getStaticPaths() {const posts = await getCollection('blog');return posts.map(post => ({params: { slug: post.id }, props: { post },}));}const { post } = Astro.props;const { Content } = await render(post);---<MarkdownPostLayout frontmatter={post.data}><Content /></MarkdownPostLayout> -
Rimuovi la definizione di
layout
nel frontmatter di ogni singolo articolo. Il tuo contenuto è ora avvolto in un layout quando viene renderizzato e questa proprietà non è più necessaria.src/content/posts/post-1.md ---layout: ../../layouts/MarkdownPostLayout.astrotitle: 'Il mio primo articolo del blog'pubDate: 2022-07-01...---
Sostituisci import.meta.glob()
con getCollection()
Sezione intitolata Sostituisci import.meta.glob() con getCollection()-
Ovunque tu abbia un elenco di articoli del blog, come la pagina Blog del tutorial (
src/pages/blog.astro/
), dovrai sostituireimport.meta.glob()
congetCollection()
(EN) come modo per recuperare contenuto e metadata dai tuoi file Markdown.src/pages/blog.astro ---import { getCollection } from "astro:content";import BaseLayout from "../layouts/BaseLayout.astro";import BlogPost from "../components/BlogPost.astro";const pageTitle = "Il mio Blog di apprendimento di Astro";const allPosts = Object.values(import.meta.glob("../pages/posts/*.md", { eager: true }));const allPosts = await getCollection("blog");--- -
Dovrai anche aggiornare i riferimenti ai dati restituiti per ogni
post
. Ora troverai i tuoi valori frontmatter sulla proprietàdata
di ogni oggetto. Inoltre, quando usi le raccolte, ogni oggettopost
avrà unoslug
di pagina, non un URL completo.src/pages/blog.astro ---import { getCollection } from "astro:content";import BaseLayout from "../layouts/BaseLayout.astro";import BlogPost from "../components/BlogPost.astro";const pageTitle = "Il mio Blog di apprendimento di Astro";const allPosts = await getCollection("blog");---<BaseLayout pageTitle={pageTitle}><p>Questo è dove pubblicherò sul mio percorso di apprendimento di Astro.</p><ul>{allPosts.map((post) => (<BlogPost url={post.url} title={post.frontmatter.title} />)}<BlogPost url={`/posts/${post.id}/`} title={post.data.title} />))}</ul></BaseLayout> -
Anche la pagina del tutorial blog genera dinamicamente una pagina per ogni tag usando
src/pages/tags/[tag].astro
e visualizza un elenco di tag susrc/pages/tags/index.astro
.Applica le stesse modifiche di sopra a questi due file:
- recupera i dati su tutti i tuoi articoli del blog usando
getCollection("blog")
invece di usareimport.meta.glob()
- accedi a tutti i valori frontmatter usando
data
invece difrontmatter
- crea un URL di pagina aggiungendo lo
slug
dell’articolo al percorso/posts/
La pagina che genera singole pagine di tag ora diventa:
src/pages/tags/[tag].astro ---import { getCollection } from "astro:content";import BaseLayout from "../../layouts/BaseLayout.astro";import BlogPost from "../../components/BlogPost.astro";export async function getStaticPaths() {const allPosts = await getCollection("blog");const uniqueTags = [...new Set(allPosts.map((post) => post.data.tags).flat())];return uniqueTags.map((tag) => {const filteredPosts = allPosts.filter((post) =>post.data.tags.includes(tag));return {params: { tag },props: { posts: filteredPosts },};});}const { tag } = Astro.params;const { posts } = Astro.props;---<BaseLayout pageTitle={tag}><p>Articoli taggati con {tag}</p><ul>{ posts.map((post) => <BlogPost url={`/posts/${post.id}/`} title={post.data.title} />) }</ul></BaseLayout>Prova tu stesso - Aggiorna la query nella pagina Indice di Tag
Sezione intitolata Prova tu stesso - Aggiorna la query nella pagina Indice di TagImporta e usa
getCollection
per recuperare i tag usati negli articoli del blog susrc/pages/tags/index.astro
, seguendo gli stessi passaggi di sopra.Mostrami il codice.
src/pages/tags/index.astro ---import { getCollection } from "astro:content";import BaseLayout from "../../layouts/BaseLayout.astro";const allPosts = await getCollection("blog");const tags = [...new Set(allPosts.map((post) => post.data.tags).flat())];const pageTitle = "Indice di Tag";---<!-- ... --> - recupera i dati su tutti i tuoi articoli del blog usando
Aggiorna qualsiasi valore frontmatter per corrispondere al tuo schema
Sezione intitolata Aggiorna qualsiasi valore frontmatter per corrispondere al tuo schemaSe necessario, aggiorna qualsiasi valore frontmatter in tutto il tuo progetto, come nel tuo layout, che non corrisponde allo schema delle tue raccolte.
Nell’esempio del tutorial del blog, pubDate
era una stringa. Ora, secondo lo schema che definisce i tipi per il frontmatter dell’articolo, pubDate
sarà un oggetto
Date
. Ora puoi approfittare di questo per usare i metodi disponibili per qualsiasi oggetto Date
per formattare la data.
Per renderizzare la data nel layout dell’articolo del blog, convertila in una stringa usando il metodo toLocaleDateString()
:
<!-- ... --><BaseLayout pageTitle={frontmatter.title}> <p>{frontmatter.pubDate.toLocaleDateString()}</p> <p><em>{frontmatter.description}</em></p> <p>Scritto da: {frontmatter.author}</p> <img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} /><!-- ... -->
Aggiorna la funzione RSS
Sezione intitolata Aggiorna la funzione RSSIl progetto del tutorial del blog include un feed RSS. Anche questa funzione deve usare getCollection()
per restituire informazioni dai tuoi articoli del blog. Genererai quindi gli item RSS usando l’oggetto data
restituito.
import rss from '@astrojs/rss';import { pagesGlobToRssItems } from '@astrojs/rss';import { getCollection } from 'astro:content';
export async function GET(context) { const posts = await getCollection("blog"); return rss({ title: 'Studente Astro | Blog', description: 'Il mio percorso di apprendimento di Astro', site: context.site, items: await pagesGlobToRssItems(import.meta.glob('./**/*.md')), items: posts.map((post) => ({ title: post.data.title, pubDate: post.data.pubDate, description: post.data.description, link: `/posts/${post.id}/`, })), customData: `<language>it-it</language>`, })}
Per l’esempio completo del tutorial del blog che usa raccolte di contenuti, vedi il branch Raccolte di contenuti del repository del tutorial.