首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Gatsbyjs页面生成

Gatsbyjs页面生成
EN

Stack Overflow用户
提问于 2020-03-25 14:58:03
回答 1查看 406关注 0票数 2

我正在用无头WordPress作为数据源开发Gatsbyjs网站。我不想在/pages中静态地生成所有页面,而是在imGatsby-node.js中通过allPages / allPosts查询和使用createPage API向页面/post模板发送数据。

但是我的页面有点复杂,它们似乎需要非常不同的查询( acf..。)

这里的最佳做法是什么?我是否应该为每个页面创建一个模板,并将数据直接映射到这些页面中?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-25 15:19:47

是的,你打到钉子了。您必须为要生成的每一种类型的页面生成模板/页。

TL;DR

您只需要创建不同的createPage操作并将它们指向不同的模板/页面。例如:

代码语言:javascript
复制
createPage({
      path: node.fields.slug,
      component: path.resolve(`./src/templates/blog-post.js`),
      context: {
        slug: node.fields.slug,
      },
    })

代码语言:javascript
复制
 createPage({
      path: node.fields.slug,
      component: path.resolve(`./src/templates/tags.js`),
      context: {
        slug: node.fields.slug,
      },
    })

长版

标准用例

代码语言:javascript
复制
exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions
  const result = await graphql(`
    query {
      allMarkdownRemark {
        edges {
          node {
            fields {
              slug
            }
          }
        }
      }
    }
  `)
  result.data.allMarkdownRemark.edges.forEach(({ node }) => {
    createPage({
      path: node.fields.slug,
      component: path.resolve(`./src/templates/blog-post.js`),
      context: {
        slug: node.fields.slug,
      },
    })
  })
}

component将定义数据可在何处使用,以及将使用哪个模板/页/组件。

如果希望使用不同的模板而不是/blog-post,则需要创建另一个createPage操作。就像这样:

代码语言:javascript
复制
exports.createPages = ({ actions, graphql }) => {
  const { createPage } = actions

  return graphql(`
    {
      allMarkdownRemark(limit: 1000) {
        edges {
          node {
            id
            fields {
              slug
            }
            frontmatter {
              tags
              templateKey
            }
          }
        }
      }
    }
  `).then(result => {
    if (result.errors) {
      result.errors.forEach(e => console.error(e.toString()))
      return Promise.reject(result.errors)
    }

    const posts = result.data.allMarkdownRemark.edges

    posts.forEach(edge => {
      const id = edge.node.id
      createPage({
        path: edge.node.fields.slug,
        tags: edge.node.frontmatter.tags,
        component: path.resolve(
          `src/templates/blog-post.js`
        ),
        // additional data can be passed via context
        context: {
          id,
        },
      })
    })

    // Tag pages:
    let tags = []
    // Iterate through each post, putting all found tags into `tags`
    posts.forEach(edge => {
      if (_.get(edge, `node.frontmatter.tags`)) {
        tags = tags.concat(edge.node.frontmatter.tags)
      }
    })
    // Eliminate duplicate tags
    tags = _.uniq(tags)

    // Make tag pages
    tags.forEach(tag => {
      const tagPath = `/tags/${_.kebabCase(tag)}/`

      createPage({
        path: tagPath,
        component: path.resolve(`src/templates/tags.js`),
        context: {
          tag,
        },
      })
    })
  })
}

没有详细介绍它的功能或方法(如果需要的话,我可以详细说明答案),重要的是您可以使用createPage操作来定义需要多少页、数据和组件。在这种情况下,blog-post.jstags.js可以在/blog-post/postSlug/tag/tagPath中找到。

承诺用例

如果你有一个小的网站或项目,以前的情况可能有效,但是如果你的项目增长,在这么多行中找到信息就会变成地狱。因此,我使用创建承诺来存储这些信息。在我的gatsby-node

代码语言:javascript
复制
const postsBuilder = require("./src/build/postsBuilder");
const tagsBuilder = require("./src/build/tagsBuilder");

exports.createPages = async ({graphql, actions}) => {
  await Promise.all(
    [
      postBuilder(graphql, actions),
      tagsBuilder(graphql, actions)
    ]
  );
};

然后,在其中一个建筑工人中:

代码语言:javascript
复制
const path = require('path')

async function postsBuilder(graphql, actions) {
  const {createPage} = actions;

  const postsQuery= await graphql(`
     {
      allMarkdownRemark(limit: 1000) {
        edges {
          node {
            id
            fields {
              slug
            }
            frontmatter {
              tags
              templateKey
            }
          }
        }
      }
    }`);

  const resultForms = postsQuery.data.allMarkdownRemark.edges;

  resultForms.map(node => {
      createPage({
        path: node.node.url + '/',
        component: whateverYouNeed,
        context: {
          name: node.node.name,
          url: node.node.url
        },
      })
  });
}

module.exports = postsBuilder;

请注意,代码可以在许多方面进行重构,这仅仅是为了展示您能够做的另一种方法。

我认为承诺的方式更具有语义性和清晰性,但在每种情况下都由您使用所需的任何东西。

参考资料:

  1. 第一个查询
  2. 第二次查询
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60851427

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档