Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Выборка из коллекций

Описанную коллекцию читают функциями из модуля astro:content. getCollection() возвращает все записи, getEntry() — одну по её идентификатору, а render() превращает текст записи в компонент, который можно вставить в страницу.

Список статей

Откройте src/pages/posts/index.astro и замените выдуманные карточки настоящими статьями:

---
import { getCollection } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
import PostCard from '../../components/PostCard.astro';
 
const posts = await getCollection('blog');
---
 
<BaseLayout title="Статьи">
  <h1>Статьи</h1>
  {posts.map((post) => (
    <PostCard title={post.data.title} url={`/posts/${post.id}`} />
  ))}
</BaseLayout>

Откройте /posts — появится по карточке на каждый файл из src/content/blog. Во фронтматтере можно писать await сразу, без обёртки в асинхронную функцию.

Что лежит в записи

ПолеЗначение для first-post.md
post.idfirst-post — имя файла без расширения
post.dataПроверенный схемой фронтматтер: title, pubDate, tags
post.bodyИсходный текст статьи в Markdown
post.collectionblog

post.data.pubDate — уже объект Date, потому что схема привела строку к дате.

Фильтр и сортировка

Вторым аргументом getCollection() принимает функцию-фильтр. Скроем черновики и отсортируем статьи от новых к старым:

---
import { getCollection } from 'astro:content';
 
const posts = (await getCollection('blog', ({ data }) => !data.draft))
  .sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
---

Статьи с draft: true во фронтматтере исчезнут из списка, а свежая статья окажется первой. Сортировка — обычный метод массива sort(): Astro не гарантирует порядок записей.

Одна запись и её текст

getEntry() находит запись по имени коллекции и id, а render() возвращает компонент Content с HTML статьи. Создайте src/pages/posts/first-post.astro:

---
import { getEntry, render } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
 
const post = await getEntry('blog', 'first-post');
if (!post) throw new Error('Статья не найдена');
 
const { Content } = await render(post);
---
 
<BaseLayout title={post.data.title}>
  <h1>{post.data.title}</h1>
  <Content />
</BaseLayout>

Откройте /posts/first-post — появится заголовок и текст статьи, превращённый из Markdown в HTML. Делать такой файл для каждой статьи не придётся: следующий урок заменит его одной динамической страницей.

Частая ошибка

Пишут post.title вместо post.data.title и получают пустое место на странице. Всё, что задано во фронтматтере, лежит в post.data, а в самой записи — служебные поля вроде id. Редактор подсказывает правильный путь, если подключены типы Astro.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.