使用 Gatsby.js 搭建靜態博客 4 標籤系統

原文連接:https://ssshooter.com/2018-12...javascript

回顧:使用 Gatsby.js 搭建靜態博客 3 樣式調整java

官方自帶標籤系統教程,英語過關能夠直接閱讀官方教程node

如下說一下重點:segmentfault

提示:如下全部查詢均可以在 localhost:8000/___graphql 測試數據結構

創建標籤系統只須要如下步驟:ssh

在 md 文件添加 tags

---
title: "A Trip To the Zoo"
tags: ["animals", "Chicago", "zoos"]
---

用 graphQL 查詢文章標籤

{
  allMarkdownRemark(
    sort: { order: DESC, fields: [frontmatter___date] }
    limit: 1000
  ) {
    edges {
      node {
        frontmatter {
          path
          tags // 也就添加了這部分
        }
      }
    }
  }
}

製做標籤頁面模板(/tags/{tag}

標籤頁面結構不難,與以前的文章頁面差很少,區別在於標籤的查詢:post

// 注意 filter
export const pageQuery = graphql`
  query($tag: String) {
    allMarkdownRemark(
      limit: 2000
      sort: { fields: [frontmatter___date], order: DESC }
      filter: { frontmatter: { tags: { in: [$tag] } } }
    ) {
      totalCount
      edges {
        node {
          frontmatter {
            title
            path
          }
        }
      }
    }
  }
`

修改 gatsby-node.js,渲染標籤頁模板

const path = require("path")
const _ = require("lodash")

exports.createPages = ({ actions, graphql }) => {
  const { createPage } = actions

  const blogPostTemplate = path.resolve("src/templates/blog.js")
  const tagTemplate = path.resolve("src/templates/tags.js")

  return graphql(`
    {
      allMarkdownRemark(
        sort: { order: DESC, fields: [frontmatter___date] }
        limit: 2000
      ) {
        edges {
          node {
            frontmatter {
              path
              tags
            }
          }
        }
      }
    }
  `).then(result => {
    if (result.errors) {
      return Promise.reject(result.errors)
    }

    const posts = result.data.allMarkdownRemark.edges

    posts.forEach(({ node }) => {
      createPage({
        path: node.frontmatter.path,
        component: blogPostTemplate,
      })
    })

    let tags = []
    // 獲取全部文章的 `tags`
    _.each(posts, edge => {
      if (_.get(edge, "node.frontmatter.tags")) {
        tags = tags.concat(edge.node.frontmatter.tags)
      }
    })
    // 去重
    tags = _.uniq(tags)

    // 建立標籤頁
    tags.forEach(tag => {
      createPage({
        path: `/tags/${_.kebabCase(tag)}/`,
        component: tagTemplate,
        context: {
          tag,
        },
      })
    })
  })
}

若是你要把標籤頁也分頁,多加一個循環就行,道理跟主頁分頁都是同樣的:測試

tags.forEach(tag => {
    const total = tag.totalCount
    const numPages = Math.ceil(total / postsPerPage)
    Array.from({ length: numPages }).forEach((_, i) => {
    createPage({
        path:
        i === 0
            ? `/tag/${tag.fieldValue}`
            : `/tag/${tag.fieldValue}/${i + 1}`,
        component: tagTemplate,
        context: {
        tag: tag.fieldValue,
        currentPage: i + 1,
        totalPage: numPages,
        limit: postsPerPage,
        skip: i * postsPerPage,
        },
    })
    })
})

這裏僅僅是把查詢到的文章的全部標籤都抽取出來,用以生成標籤頁,可是標籤具體內容的獲取依賴於標籤頁自己的查詢ui

製做 /tags 頁面展現全部標籤

重點一樣是查詢部分:code

export const pageQuery = graphql`
  query {
    site {
      siteMetadata {
        title
      }
    }
    allMarkdownRemark(
      limit: 2000
      filter: { frontmatter: { published: { ne: false } } }
    ) {
      group(field: frontmatter___tags) {
        fieldValue
        totalCount
      }
    }
  }
`

fieldValue 是標籤名,totalCount 是包含該標籤的文章總數。

在以前寫好的文章頁渲染標籤

就是查詢的時候多一個標籤字段,而後渲染上,完事。

下一步

再次提醒,對於數據結構模糊的話直接在 localhost:8000/___graphql 查一下就很清晰了。如今這個 blog 已經愈來愈完善,接下來添加的功能能夠說都是非必須的了,下一步先說說頁面部署。

相關文章
相關標籤/搜索