构建一个标签索引页
现在你已经为每个标签创建了单独的页面,是时候为它们创建链接了。
准备好去……
- 使用
/pages/folder/index.astro
路由模式添加一个新页面 - 显示所有唯一标签的列表,并链接到每个标签页面
- 更新你的网站,添加指向这个新标签页面的导航链接
使用 /pages/folder/index.astro
路由模式
标题为“使用 /pages/folder/index.astro 路由模式”的部分要将标签索引页添加到你的网站,你可以在 src/pages/tags.astro
创建一个新文件。
但是,由于你已经有了 /tags/
目录,你可以利用 Astro 的另一种路由模式,并将所有与标签相关的文件放在一起。
亲自动手 - 创建一个标签索引页
标题为“亲自动手 - 创建一个标签索引页”的部分-
在
src/pages/tags/
目录中创建一个新文件index.astro
。 -
导航到
https://:4321/tags
并验证你的网站现在在此 URL 上包含一个页面。它将是空的,但它确实存在。 -
在
src/pages/tags/index.astro
创建一个使用你的布局的最小化页面。你以前做过这个!展开以查看步骤
-
在
src/pages/tags/
中创建一个新的页面组件。显示文件名
index.astro -
导入并使用你的
<BaseLayout>
。显示代码
src/pages/tags/index.astro ---import BaseLayout from '../../layouts/BaseLayout.astro';---<BaseLayout></BaseLayout> -
定义一个页面标题,并将其作为组件属性传递给你的布局。
显示代码
src/pages/tags/index.astro ---import BaseLayout from '../../layouts/BaseLayout.astro';const pageTitle = "Tag Index";---<BaseLayout pageTitle={pageTitle}></BaseLayout>
-
-
再次检查你的浏览器预览,你应该会看到一个格式化的页面,准备好添加内容了!
创建一个标签数组
标题为“创建一个标签数组”的部分你之前已经使用 map()
从数组中显示列表项。如果定义一个包含所有标签的数组,然后在这个页面上以列表形式显示它们,会是什么样子?
查看代码
---import BaseLayout from '../../layouts/BaseLayout.astro';const tags = ['astro', 'blogging', 'learning in public', 'successes', 'setbacks', 'community']const pageTitle = "Tag Index";---<BaseLayout pageTitle={pageTitle}> <ul> {tags.map((tag) => <li>{tag}</li>)} </ul></BaseLayout>
你可以这样做,但这样一来,每次你在未来的博客文章中使用新标签时,都需要回到这个文件来更新你的数组。
幸运的是,你已经知道一种方法,可以用一行代码从所有 Markdown 文件中获取数据,然后返回所有标签的列表。
-
在
src/pages/tags/index.astro
中,将那行代码添加到 frontmatter 脚本中,这将使你的页面能够访问每个.md
博客文章文件的数据。查看代码
src/pages/tags/index.astro ---import BaseLayout from '../../layouts/BaseLayout.astro';const allPosts = Object.values(import.meta.glob('../posts/*.md', { eager: true }));const pageTitle = "Tag Index";--- -
接下来,将以下这行 JavaScript 添加到你的页面组件中。这与你在
src/pages/tags/[tag].astro
中使用的依赖 Astro 内置 TypeScript 支持的代码相同,用于返回唯一标签的列表。src/pages/tags/index.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 = "Tag Index";---
创建你的标签列表
标题为“创建你的标签列表”的部分这次不是在无序列表中创建项目,而是在一个 <div>
内部为每个项目创建一个 <p>
。这个模式看起来应该很熟悉!
-
将以下代码添加到你的组件模板中
src/pages/tags/index.astro <BaseLayout pageTitle={pageTitle}><div>{tags.map((tag) => <p>{tag}</p>)}</div></BaseLayout>在你的浏览器预览中,验证你是否能看到列出的标签。如果任何博客文章缺少标签,或者它们的格式不正确,Astro 的内置 TypeScript 支持将向你显示错误,以便你检查和更正你的代码。
-
为了使每个标签链接到其自己的页面,为每个标签名称添加以下
<a>
链接src/pages/tags/index.astro <BaseLayout pageTitle={pageTitle}><div>{tags.map((tag) => (<p><a href={`/tags/${tag}`}>{tag}</a></p>))}</div></BaseLayout>
为你的标签列表添加样式
标题为“为你的标签列表添加样式”的部分-
添加以下 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> -
通过将以下
<style>
标签添加到此页面来定义这些新的 CSS 类src/pages/tags/index.astro <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> -
在
https://: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>
将此页面添加到你的导航栏
标题为“将此页面添加到你的导航栏”的部分现在,你可以导航到 https://:4321/tags
并看到这个页面。在这个页面上,你可以点击链接到你各自的标签页面。
但是,你仍然需要让你网站上的其他页面能够发现这些页面。
-
在你的
Navigation.astro
组件中,包含一个指向这个新标签索引页的链接。给我看代码
src/components/Navigation.astro <a href="/">Home</a><a href="/about/">About</a><a href="/blog/">Blog</a><a href="/tags/">Tags</a>
挑战:在你的博客文章布局中包含标签
标题为“挑战:在你的博客文章布局中包含标签”的部分你现在已经编写了所有需要的代码,也可以在每篇博客文章上显示标签列表,并将它们链接到各自的标签页面。你可以重用已有的工作!
按照以下步骤操作,然后通过与最终代码示例比较来检查你的工作。
-
从
src/pages/tags/index.astro
复制<div class="tags">...</div>
和<style>...</style>
,并在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.toString().slice(0,10)}</p><p>Written by: {frontmatter.author}</p><img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} /><div class="tags">{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>
在这段代码生效之前,你需要对粘贴到 MarkdownPostLayout.astro
中的代码进行一个小小的编辑。你能找出是什么吗?
给我一个提示
其他 props(例如 title、author 等)在你的布局模板中是如何编写的?你的布局是如何从单篇博客文章中接收 props 的?
再给我一个提示!
为了在你的布局中使用来自 .md
博客文章的 props(传递的值),比如标签,你需要在值前面加上一个特定的词。
显示代码!
<div class="tags"> {frontmatter.tags.map((tag: string) => ( <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p> ))} </div>
代码核查:MarkdownPostLayout
标题为“代码核查: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>Written by: {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>
知识测验
标题为“测试你的知识”的部分将每个文件路径与将在相同路由下创建页面的另一个文件路径匹配。
-
src/pages/categories.astro
-
src/pages/posts.astro
-
src/pages/products/shoes/index.astro