【问题标题】:How to get updated / lastmod value for static files for sitemap Gatsby如何获取站点地图 Gatsby 的静态文件的更新/lastmod 值
【发布时间】:2022-01-06 08:42:09
【问题描述】:

我一直在使用 Gatsby,并一直在尝试为静态页面 (src/pages) 创建一个带有 lastmod 值的 sitemap。我看到了一个随机代码 sn-p,其中有人在他的 gatsby-config.js 中运行了下面的查询,并且能够得到他上次修改它们的日期。

allSitePage {
  nodes {
    path
    context {
      updated
    }
  }
}

我没能达到同样的成就。

这是我迄今为止尝试过的。我假设他正在使用上下文管理器并在他的 js 文件中设置上下文,并在每次编辑文件时手动更新上下文的值。

const Updated = React.createContext('2021-11-29')

class IndexPage extends React.Component {
  render() {
    return (
      <div>
        {/* Example */}
      </div>
    )
  }
}

/* Also tried IndexPage.contextType = Updated */
IndexPage.useContext = Updated

export default IndexPage

我再次运行了查询,但无法传递要在graphql 查询中看到的值。这是我在 Graphql 操场上运行的查询。

query MyQuery {
  allSitePage {
    nodes {
      id
      context {
        updated
      }
    }
  }
}

这就是我的整个数据结构在 Graphql 游乐场中的样子。

在创建站点地图时如何获取/设置要在gatsby-config.js 中使用的updated 值?

【问题讨论】:

    标签: reactjs graphql gatsby


    【解决方案1】:
    "allSitePage": {
          "nodes": [
            {
              "path": "/signup/united-states/new-york/"
            },
            {
              "path": "/signup/united-kingdom/london/"
            }
          ]
    }
    

    如果您的项目具有嵌套页面结构,请使用以下代码。

    {
      resolve: "gatsby-source-filesystem",
      options: {
        name: "pages",
        path: "./src/pages/",
      },
    },
    `gatsby-transformer-gitinfo`, {
      resolve: "gatsby-plugin-sitemap",
      options: {
        query: `{
          site {
            siteMetadata {
              siteUrl
            }
          }
          allSitePage {
            nodes {
              path
            }
          }
          allFile(filter: {sourceInstanceName: {eq: "pages"}}) {
            edges {
              node {
                fields {
                  gitLogLatestDate
                }
                relativePath
              }
            }
          }
        }`,
        resolvePages: ({
          allSitePage: {
            nodes: sitePages
          },
          allFile: {
            edges: pageFiles
          }
        }) => {
          return sitePages.map(page => {
            const pageFile = pageFiles.find(({
              node
            }) => {
              let fileName = node.relativePath.split('.').slice(0, -1).join('.')
              fileName = fileName === 'index' ? '/' : `/${fileName.replace('/index','')}/`
              return page.path === fileName;
            });
    
            return { ...page, ...pageFile?.node?.fields }
          })
        },
        serialize: ({
          path,
          gitLogLatestDate
        }) => {
          return {
            url: path,
            lastmod: gitLogLatestDate
          }
        },
        createLinkInHead: true,
      },
    }

    【讨论】:

      【解决方案2】:

      1.使用gatsby-source-filesystem 将静态页面文件添加到您的文件系统,以便您可以查询它们。

      在gatsby-config.js 中添加以下内容:

      {
        resolve: "gatsby-source-filesystem",
        options: {
          name: "pages",
          path: "./src/pages/",
        },
      },
      

      注意:您在此处用于name 属性的任何内容都将成为您在查询中过滤的内容。

      2。将gatsby-transformer-gitinfo 添加到您的项目中,以在最新提交的File 字段上添加一些git 信息。 (plugin docs)

      只需像这样在步骤 1 下声明它:

      {
        resolve: "gatsby-source-filesystem",
        options: {
          name: "pages",
          path: "./src/pages/",
        },
      },
      `gatsby-transformer-gitinfo`,
      

      我们使用这个插件是因为 Gatsby 的 File 节点中的任何 modifiedTime/mtime/changeTime/ctime 字段在部署时都会被覆盖,因为 git 不会记录或保留文件时间戳元数据。

      3.现在我们已将所有必要的数据添加到 GraphQL 中,并且可以对其进行查询以查看其外观:

      query MyQuery {
        site {
          siteMetadata {
            siteUrl
          }
        }
        allSitePage {
          nodes {
            path
          }
        }
        allFile(filter: {sourceInstanceName: {eq: "pages"}}) {
          edges {
            node {
              fields {
                gitLogLatestDate
              }
              name
            }
          }
        }
      }
      

      注意: sourceInstanceName 应该等于您在第 1 步中为 options.name 设置的任何值。

      查询结果应如下所示:

      {
        "data": {
          "site": {
            "siteMetadata": {
              "siteUrl": "https://www.example.com"
            }
          },
          "allSitePage": {
            "nodes": [
              {
                "path": "/dev-404-page/"
              },
              {
                "path": "/404/"
              },
              {
                "path": "/404.html"
              },
              {
                "path": "/contact/"
              },
              {
                "path": "/features/"
              },
              {
                "path": "/"
              },
              {
                "path": "/privacy/"
              },
              {
                "path": "/terms/"
              }
            ]
          },
          "allFile": {
            "edges": [
              {
                "node": {
                  "fields": {
                    "gitLogLatestDate": "2021-12-09 23:18:29 -0600"
                  },
                  "name": "404"
                }
              },
              {
                "node": {
                  "fields": {
                    "gitLogLatestDate": "2021-12-09 23:18:29 -0600"
                  },
                  "name": "contact"
                }
              },
              {
                "node": {
                  "fields": {
                    "gitLogLatestDate": "2021-12-09 23:18:29 -0600"
                  },
                  "name": "privacy"
                }
              },
              {
                "node": {
                  "fields": {
                    "gitLogLatestDate": "2021-12-07 19:11:12 -0600"
                  },
                  "name": "index"
                }
              },
              {
                "node": {
                  "fields": {
                    "gitLogLatestDate": "2021-12-09 23:18:29 -0600"
                  },
                  "name": "terms"
                }
              },
              {
                "node": {
                  "fields": {
                    "gitLogLatestDate": "2021-12-09 23:18:29 -0600"
                  },
                  "name": "features"
                }
              }
            ]
          }
        },
        "extensions": {}
      }
      

      4.现在让我们把它们放在一起gatsby-config.js:

      {
        resolve: "gatsby-source-filesystem",
        options: {
          name: "pages",
          path: "./src/pages/",
        },
      },
      `gatsby-transformer-gitinfo`,
      {
        resolve: "gatsby-plugin-sitemap",
        options: {
          query: `{
            site {
              siteMetadata {
                siteUrl
              }
            }
            allSitePage {
              nodes {
                path
              }
            }
            allFile(filter: {sourceInstanceName: {eq: "pages"}}) {
              edges {
                node {
                  fields {
                    gitLogLatestDate
                  }
                  name
                }
              }
            }
          }`,
          resolvePages: ({
            allSitePage: { nodes: sitePages },
            allFile: { edges: pageFiles }
          }) => {
            return sitePages.map(page => {
              const pageFile = pageFiles.find(({ node }) => {
                const fileName = node.name === 'index' ? '/' : `/${node.name}/`;
                return page.path === fileName;
              });
      
              return { ...page, ...pageFile?.node?.fields }
            })
          },
          serialize: ({ path, gitLogLatestDate }) => {
            return {
              url: path,
              lastmod: gitLogLatestDate
            }
          },
          createLinkInHead: true,
        },
      }
      

      gatsby-plugin-sitemap 选项的解释:

      • query 不言自明

      • resolvePages

        • 从query 中获取结果,因此我们可以使用解构将allSitePage 和allFile 节点/边分配给变量。
        • 通过sitePages(allSitePage.nodes)映射,使用page.path查找匹配文件name。
          • 如果文件name 是index,则使用/ 进行匹配,因为路径不是/index/,否则只需将文件name 包装在分隔符中。
        • 返回合并后的页面对象和包含 git 信息的匹配文件对象
        • (来自resolvePages 的对象数组成为插件代码中的allPages 对象)
      • serialize

        • 这个函数映射到allPages,也就是来自resolvePages的页面对象数组,所以我们可以再次使用解构来获取每个页面的path和gitLogLatestDate。
        • 返回属性:
          • url:插件将使用查询中的siteMetaData.siteUrl 并附加此处分配的任何值以生成完整的 URL。

          • lastmod: 期望一个有效的时间值并且总是输出一个完整的 ISO8601 字符串,不管传入的格式是什么。

            注意:目前,似乎没有办法将lastmod 格式化为日期,只能通过gatsby-plugin-sitemap。这是因为 gatsby-plugin-sitemap 在底层使用了这个 sitemap 库,而该库的某些组件有一个 lastmodDateOnly 标志,可以切断时间字符串,gatsby-plugin-sitemap 不使用它们。

      • createLinkInHead: 链接站点地图索引在您网站的头部

      5.最后,运行gatsby build,您应该会看到结果显示在public/sitemap/sitemap-0.xml

      (好像gatsby-plugin-sitemap 最近切换到了这个位置,所以如果您使用的是旧版本的插件,可能会在其他地方。)

      结果应如下所示:

      <?xml version="1.0" encoding="UTF-8"?>
      <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"
              xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
              xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
          <url>
              <loc>https://www.example.com/contact/</loc>
              <lastmod>2021-12-10T05:18:29.000Z</lastmod>
          </url>
          <url>
              <loc>https://www.example.com/features/</loc>
              <lastmod>2021-12-10T05:18:29.000Z</lastmod>
          </url>
          <url>
              <loc>https://www.example.com/</loc>
              <lastmod>2021-12-08T01:11:12.000Z</lastmod>
          </url>
          <url>
              <loc>https://www.example.com/privacy/</loc>
              <lastmod>2021-12-10T05:18:29.000Z</lastmod>
          </url>
          <url>
              <loc>https://www.example.com/terms/</loc>
              <lastmod>2021-12-10T05:18:29.000Z</lastmod>
          </url>
      </urlset>
      

      额外的,可能有用的细节 - 我正在使用的所有东西的版本:

      "gatsby": "^4.0.0",
      "gatsby-plugin-sitemap": "^5.3.0",
      "gatsby-source-filesystem": "^4.3.0",
      "gatsby-transformer-gitinfo": "^1.1.0",
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-04-04
        • 1970-01-01
        • 2021-10-10
        • 2018-02-22
        • 2020-05-22
        • 2020-11-08
        • 2021-10-31
        相关资源
        最近更新 更多