Пропустить до содержимого

Создание страницы индекса тегов

Теперь, когда у вас есть отдельные страницы для каждого тега, давайте создадим ссылки на них.

Приготовьтесь к…

  • Добавить новую страницу, используя шаблон маршрутизации /my-folder/index.astro
  • Отобразить список всех ваших уникальных тегов, сделав ссылку на каждую страницу тега
  • Обновить ваш сайт, добавив навигационные ссылки на эту новую страницу Теги

Используйте шаблон маршрутизации /folder/index.astro

Заголовок раздела Используйте шаблон маршрутизации /folder/index.astro

Чтобы добавить страницу индекса тегов на ваш веб-сайт, вы можете создать новый файл src/pages/tags.astro.

Однако, поскольку у вас уже есть каталог /tags/, вы можете воспользоваться другим шаблоном маршрутизации в Astro и хранить все свои файлы, связанные с тегами, вместе.

Попробуйте сами - Создайте страницу индекса тегов

Заголовок раздела Попробуйте сами - Создайте страницу индекса тегов
  1. Создайте новый файл index.astro в каталоге src/pages/tags/.

  2. Перейдите по адресу http://localhost:4321/tags и убедитесь, что ваш сайт теперь содержит страницу по этому URL. Она будет пустой, но она будет существовать.

  3. Создайте минимальную страницу в src/pages/tags/index.astro, которая использует ваш макет. Вы уже делали это раньше!

    Раскройте, чтобы увидеть шаги
    1. Создайте новый компонент страницы в src/pages/tags/.

      Показать имя файла
      index.astro
    2. Импортируйте и используйте <BaseLayout>.

      Показать код
      src/pages/tags/index.astro
      ---
      import BaseLayout from '../../layouts/BaseLayout.astro';
      ---
      <BaseLayout></BaseLayout>
    3. Определите заголовок страницы и передайте его в ваш макет в качестве атрибута компонента.

      Показать код
      src/pages/tags/index.astro
      ---
      import BaseLayout from '../../layouts/BaseLayout.astro';
      const pageTitle = "Индекс тегов";
      ---
      <BaseLayout pageTitle={pageTitle}></BaseLayout>
  4. Проверьте предварительный просмотр в браузере еще раз, и у вас должна быть отформатированная страница, готовая к добавлению контента!

Ранее вы отображали элементы в списке из массива с помощью map(). Как бы вы определили массив всех ваших тегов и затем отобразили их в списке на этой странице?

Посмотрите код
src/pages/tags/index.astro
---
import BaseLayout from '../../layouts/BaseLayout.astro';
const tags = ["astro", "successes", "community", "setbacks", "learning in public"];
const pageTitle = "Индекс тегов";
---
<BaseLayout pageTitle={pageTitle}>
<ul>
{tags.map((tag) => <li>{tag}</li>)}
</ul>
</BaseLayout>

Вы можете сделать это, но вам придется возвращаться к этому файлу и обновлять свой массив каждый раз, когда вы используете новый тег в будущей записи в блоге.

К счастью, у вас уже есть способ получить данные из всех ваших файлов Markdown в одной строке кода, а затем вернуть список всех ваших тегов.

  1. В файле src/pages/tags/index.astro добавьте строку кода в скрипт frontmatter, которая даст вашей странице доступ к данным из каждого файла блога .md.

    Посмотрите код
    src/pages/tags/index.astro
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    const allPosts = await Astro.glob('../posts/*.md');
    const pageTitle = "Индекс тегов";
    ---
  2. Затем добавьте следующую строку JavaScript в ваш компонент страницы. Это то же самое, что мы использовали в src/pages/tags/[tag].astro, чтобы вернуть список уникальных тегов.

    src/pages/tags/index.astro
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    const allPosts = await Astro.glob('../posts/*.md');
    const tags = [...new Set(allPosts.map((post) => post.frontmatter.tags).flat())];
    const pageTitle = "Индекс тегов";
    ---

Вместо создания элементов в неупорядоченном списке на этот раз создайте один <p> для каждого элемента внутри <div>. Шаблон должен вам быть знакомым!

  1. Добавьте следующий код в ваш шаблон компонента:

    src/pages/tags/index.astro
    <BaseLayout pageTitle={pageTitle}>
    <div>{tags.map((tag) => <p>{tag}</p>)}</div>
    </BaseLayout>

    В предварительном просмотре в браузере убедитесь, что вы видите свои теги в списке.

  2. Чтобы сделать каждый тег ссылкой на свою собственную страницу, добавьте следующую ссылку <a> для каждого имени тега:

    src/pages/tags/index.astro
    <BaseLayout pageTitle={pageTitle}>
    <div>
    {tags.map((tag) => (
    <p><a href={`/tags/${tag}`}>{tag}</a></p>
    ))}
    </div>
    </BaseLayout>
  1. Добавьте следующие CSS-классы, чтобы стилизовать как ваш <div>, так и каждый <p>, который будет сгенерирован. Примечание: Astro использует синтаксис HTML для добавления имен классов!

    src/pages/tags/index.astro
    <BaseLayout pageTitle={pageTitle}>
    <div class="tags">
    {tags.map((tag) => (
    <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
    ))}
    </div>
    </BaseLayout>
  2. Определите эти новые CSS-классы, добавив следующий тег <style> на этой странице:

    src/pages/tags/index.astro
    <style>
    a {
    color: #00539F;
    }
    .tags {
    display: flex;
    flex-wrap: wrap;
    margin: 0 auto;
    }
    .tag {
    margin: 0.25em;
    border: dotted 1px #a1a1a1;
    border-radius: .5em;
    padding: .5em 1em;
    font-size: 1.15em;
    background-color: #F8FCFD;
    }
    </style>
  3. Проверьте предварительный просмотр в браузере по адресу http://localhost:4321/tags, чтобы убедиться, что у вас есть новые стили и что каждый из тегов на странице имеет рабочую ссылку на свою собственную страницу тега.

Вот как должна выглядеть ваша новая страница:

src/pages/tags/index.astro
---
import BaseLayout from '../../layouts/BaseLayout.astro';
const allPosts = await Astro.glob('../posts/*.md');
const tags = [...new Set(allPosts.map((post) => post.frontmatter.tags).flat())];
const pageTitle = "Tag Index";
---
<BaseLayout pageTitle={pageTitle}>
<div class="tags">
{tags.map((tag) => (
<p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
))}
</div>
</BaseLayout>
<style>
a {
color: #00539F;
}
.tags {
display: flex;
flex-wrap: wrap;
margin: 0 auto;
}
.tag {
margin: 0.25em;
border: dotted 1px #a1a1a1;
border-radius: .5em;
padding: .5em 1em;
font-size: 1.15em;
background-color: #F8FCFD;
}
</style>

Добавьте эту страницу в вашу навигацию

Заголовок раздела Добавьте эту страницу в вашу навигацию

В данный момент вы можете перейти по адресу http://localhost:4321/tags и увидеть эту страницу. С этой страницы вы можете переходить по ссылкам на отдельные страницы тегов.

Но вам все еще нужно сделать эти страницы доступными с других страниц вашего веб-сайта.

  1. В вашем компоненте Navigation.astro добавьте ссылку на эту новую страницу индекса тегов.

    Покажи мне код
    src/components/Navigation.astro
    <a href="/">Главная</a>
    <a href="/about/">О нас</a>
    <a href="/blog/">Блог</a>
    <a href="/tags/">Теги</a>

Задание: Включите теги в макет вашей записи блога

Заголовок раздела Задание: Включите теги в макет вашей записи блога

Теперь у вас есть весь необходимый код, чтобы также отображать список тегов на каждой странице блога и связывать их со страницами тегов. У вас уже есть готовая работа, которую вы можете использовать повторно!

Следуйте инструкциям ниже, а затем проверьте свою работу, сравнив ее с финальным образцом кода.

  1. Скопируйте <div class="tags"></div> и <style>...</style> из src/pages/tags/index.astro и используйте их внутри MarkdownPostLayout.astro:
src/layouts/MarkdownPostLayout.astro
---
import BaseLayout from './BaseLayout.astro';
const { frontmatter } = Astro.props;
---
<BaseLayout pageTitle={frontmatter.title}>
<p><em>{frontmatter.description}</em></p>
<p>{frontmatter.pubDate.slice(0,10)}</p>
<p>Написал: {frontmatter.author}</p>
<img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} />
<div class="tags">
{tags.map((tag) => (
<p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
))}
</div>
<slot />
</BaseLayout>
<style>
a {
color: #00539F;
}
.tags {
display: flex;
flex-wrap: wrap;
margin: 0 auto;
}
.tag {
margin: 0.25em;
border: dotted 1px #a1a1a1;
border-radius: .5em;
padding: .5em 1em;
font-size: 1.15em;
background-color: #F8FCFD;
}
</style>

Перед тем, как этот код заработает, вам нужно внести одну небольшую правку в код, который вы вставили в MarkdownPostLayout.astro. Можете понять, что это за правка?

Дайте мне подсказку

Как другие свойства (например, заголовок, автор и т. д.) записаны в вашем макете шаблона? Как ваш макет получает свойства от отдельной записи блога?

Дайте мне еще одну подсказку!

Чтобы использовать свойства (переданные значения) из файла .md в вашем макете, например, теги, вам нужно добавить префикс к значению.

Покажите мне код!
src/layouts/MarkdownPostLayout.astro
<div class="tags">
{frontmatter.tags.map((tag) => (
<p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
))}
</div>

Чтобы проверить свою работу, или если вы просто хотите скопировать полный, корректный код в MarkdownPostLayout.astro, вот как должен выглядеть ваш компонент Astro:

src/layouts/MarkdownPostLayout.astro
---
import BaseLayout from './BaseLayout.astro';
const { frontmatter } = Astro.props;
---
<BaseLayout pageTitle={frontmatter.title}>
<p><em>{frontmatter.description}</em></p>
<p>{frontmatter.pubDate.slice(0,10)}</p>
<p>Автор: {frontmatter.author}</p>
<img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} />
<div class="tags">
{frontmatter.tags.map((tag) => (
<p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
))}
</div>
<slot />
</BaseLayout>
<style>
a {
color: #00539F;
}
.tags {
display: flex;
flex-wrap: wrap;
margin: 0 auto;
}
.tag {
margin: 0.25em;
border: dotted 1px #a1a1a1;
border-radius: .5em;
padding: .5em 1em;
font-size: 1.15em;
background-color: #F8FCFD;
}
</style>

Сопоставьте каждый файловый путь со вторым файловым путем, который создаст страницу по тому же маршруту.

  1. src/pages/categories.astro

  2. src/pages/posts.astro

  3. src/pages/products/shoes/index.astro