Создание страниц тегов
Приготовьтесь…
- Создайть страницу для генерации нескольких страниц
- Указать, какие маршруты страниц следует построить, и передать каждой странице свои собственные свойства
Динамическая маршрутизация страниц
Заголовок раздела Динамическая маршрутизация страницВы можете динамически создавать целые наборы страниц с помощью файлов .astro, которые экспортируют функцию getStaticPaths().
Создание страниц динамически
Заголовок раздела Создание страниц динамически-
Создайте новый файл по адресу
src/pages/tags/[tag].astro. (Вам придется создать новую папку.) Обратите внимание, что имя файла ([tag].astro) использует квадратные скобки. Вставьте следующий код в файл:src/pages/tags/[tag].astro ---import BaseLayout from '../../layouts/BaseLayout.astro';export async function getStaticPaths() {return [{ params: { tag: "astro" } },{ params: { tag: "successes" } },{ params: { tag: "community" } },{ params: { tag: "blogging" } },{ params: { tag: "setbacks" } },{ params: { tag: "learning in public" } },];}const { tag } = Astro.params;---<BaseLayout pageTitle={tag}><p>Посты с тегом {tag}</p></BaseLayout>Функция
getStaticPathsвозвращает массив маршрутов страниц, и все страницы по этим маршрутам будут использовать один и тот же шаблон, определенный в файле. -
Если вы настроили свои блог-посты, замените отдельные значения тегов (например, “astro”, “successes”, “community” и т.д.) на теги, используемые в ваших собственных постах.
-
Убедитесь, что каждый блог-пост содержит хотя бы один тег, написанный в виде массива, например,
tags: ["blogging"]. -
Перейдите по адресу
http://localhost:4321/tags/astroв предварительном просмотре вашего браузера, и вы должны увидеть страницу, созданную динамически из[tag].astro. Проверьте, созданы ли у вас страницы для каждого из ваших тегов по адресам/tags/successes,/tags/communityи/tags/learning%20in%20publicи т.д., или для каждого из ваших пользовательских тегов. Возможно, вам придется сначала выйти и перезапустить сервер разработки, чтобы увидеть эти новые страницы.
Использование props в динамических маршрутах
Заголовок раздела Использование props в динамических маршрутах-
Добавьте следующие props в вашу функцию
getStaticPaths(), чтобы сделать данные из всех ваших блог-постов доступными для каждого маршрута страницы.Обязательно предоставьте каждому маршруту в вашем массиве новые props, а затем сделайте эти props доступными для вашего шаблона компонента за пределами вашей функции.
src/pages/tags/[tag].astro ---import BaseLayout from '../../layouts/BaseLayout.astro';export async function getStaticPaths() {const allPosts = await Astro.glob('../posts/*.md');return [{params: {tag: "astro"}, props: {posts: allPosts}},{params: {tag: "successes"}, props: {posts: allPosts}},{params: {tag: "community"}, props: {posts: allPosts}},{params: {tag: "blogging"}, props: {posts: allPosts}},{params: {tag: "setbacks"}, props: {posts: allPosts}},{params: {tag: "learning in public"}, props: {posts: allPosts}}]}const { tag } = Astro.params;const { posts } = Astro.props;--- -
Отфильтруйте ваш список постов, чтобы включить только те посты, которые содержат собственный тег страницы.
/src/pages/tags/[tag].astro ---const { tag } = Astro.params;const { posts } = Astro.props;const filteredPosts = posts.filter((post) => post.frontmatter.tags.includes(tag));--- -
Теперь вы можете обновить ваш HTML-шаблон, чтобы показать список каждого блог-поста, содержащего собственный тег страницы. Добавьте следующий код в
[tag].astro:src/pages/tags/[tag].astro <BaseLayout pageTitle={tag}><p>Посты с тегом {tag}</p><ul>{filteredPosts.map((post) => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}</ul></BaseLayout> -
Вы даже можете рефакторить этот код, чтобы использовать ваш компонент
<BlogPost />вместо этого! (Не забудьте импортировать этот компонент в начале файла[tag].astro.)src/pages/tags/[tag].astro <BaseLayout pageTitle={tag}><p>Посты с тегом {tag}</p><ul>{filteredPosts.map((post) => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}{filteredPosts.map((post) => <BlogPost url={post.url} title={post.frontmatter.title}/>)}</ul></BaseLayout> -
Проверьте предварительный просмотр в вашем браузере для ваших отдельных страниц с тегами, и теперь вы должны увидеть список всех ваших блог-постов, содержащих этот конкретный тег.
Анализируйте шаблон
Заголовок раздела Анализируйте шаблонДля каждого из следующих укажите, написан ли код внутри функции getStaticPath(), или вне её.
-
Вызов
Astro.glob()для получения информации обо всех ваших файлах.md, которую нужно передать каждому маршруту страницы. -
Список маршрутов, которые должны быть сгенерированы (возвращены)
getStaticPaths() -
Полученные значения
propsиparams, которые будут использоваться в HTML-шаблоне.
Если вам нужна информация для создания маршрутов страниц, напишите её внутри getStaticPaths().
Чтобы получить информацию в HTML-шаблоне маршрута страницы, напишите её вне getStaticPaths().
Продвинутый JavaScript: Генерация страниц из существующих тегов
Заголовок раздела Продвинутый JavaScript: Генерация страниц из существующих теговТеперь ваши страницы с тегами статически определены в [tag].astro. Если вы добавите новый тег к сообщению в блоге, вам также придется вернуться на эту страницу и обновить маршруты страниц.
Следующий пример показывает, как заменить код на этой странице кодом, который будет автоматически искать и генерировать страницы для каждого тега, используемого на ваших страницах блога.
Даже если это выглядит сложно, вы можете попробовать следовать инструкциям и самостоятельно построить эту функцию! Если вы не хотите сейчас разбираться с необходимым JavaScript, вы можете перейти к готовому примеру кода и использовать его напрямую в своем проекте, заменяя существующий контент.
-
Убедитесь, что все ваши блог-посты содержат теги
Пересмотрите каждую из ваших существующих страниц Markdown и убедитесь, что каждый пост содержит массив
tagsв его frontmatter. Даже если у вас только один тег, он все равно должен быть записан как массив, например,tags: ["blogging"]. -
Создайте массив со всеми вашими существующими тегами
Добавьте следующий код, чтобы получить список каждого тега, используемого в ваших блог-постах.
src/pages/tags/[tag].astro ---import BaseLayout from '../../layouts/BaseLayout.astro';export async function getStaticPaths() {const allPosts = await Astro.glob('../posts/*.md');const uniqueTags = [...new Set(allPosts.map((post) => post.frontmatter.tags).flat())];}Расскажите мне подробнее, что делает эта строчка кода!
Всё в порядке, если это не то, что вы бы сами написали!
Он проходит через каждый пост в Markdown, по одному, и объединяет каждый массив тегов в один большой массив. Затем он создает новый
Setиз всех найденных индивидуальных тегов (чтобы игнорировать повторяющиеся значения). Наконец, он преобразует этот набор в массив (без дублирования), который вы можете использовать для отображения списка тегов на вашей странице.Теперь у вас есть массив
uniqueTagsс элементами"astro","successes","community","blogging","setbacks","learning in public" -
Замените значение
returnфункцииgetStaticPathssrc/pages/tags/[tag].astro return [{params: {tag: "astro"}, props: {posts: allPosts}},{params: {tag: "successes"}, props: {posts: allPosts}},{params: {tag: "community"}, props: {posts: allPosts}},{params: {tag: "blogging"}, props: {posts: allPosts}},{params: {tag: "setbacks"}, props: {posts: allPosts}},{params: {tag: "learning in public"}, props: {posts: allPosts}}]return uniqueTags.map((tag) => {const filteredPosts = allPosts.filter((post) => post.frontmatter.tags.includes(tag));return {params: { tag },props: { posts: filteredPosts },};}); -
Функция
getStaticPathsвсегда должна возвращать список объектов, содержащихparams(как называть каждый маршрут страницы) и, возможно, любыеprops(данные, которые вы хотите передать на эти страницы). Ранее вы определили каждое имя тега, которое использовалось в вашем блоге, и передали весь список постов как свойства на каждую страницу.Теперь вы генерируете этот список объектов автоматически, используя ваш массив
uniqueTagsдля определения каждого параметра.И теперь список всех блог-постов фильтруется до его отправки на каждую страницу в качестве свойств. Обязательно удалите предыдущую строку кода, фильтрующую посты, и обновите ваш HTML-шаблон, чтобы использовать
postsвместоfilteredPosts.src/pages/tags/[tag].astro const { tag } = Astro.params;const { posts } = Astro.props;const filteredPosts = posts.filter((post) => post.frontmatter.tags.includes(tag));---<!-- --><ul>{filteredPosts.map((post) => <BlogPost url={post.url} title={post.frontmatter.title}/>)}{posts.map((post) => <BlogPost url={post.url} title={post.frontmatter.title}/>)}</ul>
Пример окончательного кода
Заголовок раздела Пример окончательного кодаЧтобы проверить свою работу, или если вы просто хотите скопировать полный, правильный код в [tag].astro, то вот как должен выглядеть ваш компонент Astro:
---import BaseLayout from '../../layouts/BaseLayout.astro';import BlogPost from '../../components/BlogPost.astro'
export async function getStaticPaths() { const allPosts = await Astro.glob('../posts/*.md');
const uniqueTags = [...new Set(allPosts.map((post) => post.frontmatter.tags).flat())];
return uniqueTags.map((tag) => { const filteredPosts = allPosts.filter((post) => post.frontmatter.tags.includes(tag)); return { params: { tag }, props: { posts: filteredPosts }, }; });}
const { tag } = Astro.params;const { posts } = Astro.props;---<BaseLayout pageTitle={tag}> <p>Posts tagged with {tag}</p> <ul> {posts.map((post) => <BlogPost url={post.url} title={post.frontmatter.title}/>)} </ul></BaseLayout>Теперь вы должны быть в состоянии посетить любую из ваших страниц с тегами в предварительном просмотре браузера.
Перейдите к http://localhost:4321/tags/community и вы должны увидеть список только ваших блог-постов с тегом community. Аналогично http://localhost:4321/tags/learning%20in%20public должен отображать список блог-постов с тегом learning in public.
В следующем разделе вы создадите навигационные ссылки на эти страницы.
Проверьте свои знания
Заголовок раздела Проверьте свои знанияВыберите термин, который соответствует описанию.
-
Функция, которая возвращает массив маршрутов страниц.
-
Процесс создания нескольких маршрутов страниц из одного файла в Astro.
-
Значение, которое определяет имя маршрута страницы, генерируемого динамически.