Перейти к содержимому

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

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

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

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

Используйте шаблон маршрутизации /pages/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>.

      Показать код

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

      Показать код

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

Создайте массив тегов

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

Посмотреть код

 ---
 import BaseLayout from '../../layouts/BaseLayout.astro';
 const tags = ["astro", "успехи", "сообщество", "неудачи", "обучение в открытом доступе"];
 const pageTitle = "Индекс тегов";
 ---
 <BaseLayout pageTitle={pageTitle}>
   <ul>
     {tags.map((tag) => <li>{tag}</li>)}
   </ul>
 </BaseLayout>

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

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

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

    Посмотреть код

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

    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    const allPosts = Object.values(import.meta.glob('../posts/*.md', { eager: true }));
    const tags = [...new Set(allPosts.map((post: any) => post.frontmatter.tags).flat())];
    const pageTitle = "Индекс тегов";
    ---

Создайте свой список тегов

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

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

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

    В предварительном просмотре браузера убедитесь, что вы видите список ваших тегов. Если какие-либо записи в блоге не имеют тегов или они неправильно отформатированы, встроенная поддержка TypeScript в Astro покажет вам ошибки, чтобы вы могли проверить и исправить свой код.

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

    <BaseLayout pageTitle={pageTitle}>
      <div>
        {tags.map((tag) => (
          <p><a href={`/tags/${tag}`}>{tag}</a></p>
        ))}
      </div>
    </BaseLayout>

Добавьте стили к вашему списку тегов

  1. Добавьте следующие CSS-классы, чтобы стилизовать как ваш <div>, так и каждый <p>, который будет сгенерирован. Примечание: Astro использует синтаксис HTML для добавления имён классов!

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

    <style>
      a {
        color: #00539F;
      }
    
      .tags {
        display: flex;
        flex-wrap: wrap;
      }
    
      .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, чтобы убедиться, что у вас есть новые стили и что каждый из тегов на странице имеет рабочую ссылку на свою собственную страницу.

Проверка кода

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

---
import BaseLayout from '../../layouts/BaseLayout.astro';
const allPosts = Object.values(import.meta.glob('../posts/*.md', { eager: true }));
const tags = [...new Set(allPosts.map((post: any) => 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;
  }

  .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 добавьте ссылку на эту новую страницу индекса тегов.

    Покажи мне код

    <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:

    ---
    import BaseLayout from './BaseLayout.astro';
    const { frontmatter } = Astro.props;
    ---
    <BaseLayout pageTitle={frontmatter.title}>
      <p><em>{frontmatter.description}</em></p>
      <p>{frontmatter.pubDate.toString().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;
      }
    
      .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 в вашем макете, например, теги, вам нужно добавить префикс к значению.

Покажите мне код!

    <div class="tags">
      {frontmatter.tags.map((tag) => (
        <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
      ))}
    </div>

Проверка кода: MarkdownPostLayout

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

---
import BaseLayout from './BaseLayout.astro';
const { frontmatter } = Astro.props;
---
<BaseLayout pageTitle={frontmatter.title}>
  <p><em>{frontmatter.description}</em></p>
  <p>{frontmatter.pubDate.toString().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: string) => (
      <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
    ))}
  </div>

  <slot />
</BaseLayout>
<style>
  a {
    color: #00539F;
  }

  .tags {
    display: flex;
    flex-wrap: wrap;
  }

  .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

Контрольный список

Ресурсы

Внести свой вклад Сообщество Поддержать