javascript - GraphQL : Overriding slugs

标签 javascript node.js reactjs gatsby

👋

我正在开始我的第一个 Gatsby 项目,并且遇到了查询“可能”并不总是存在的数据的问题。这是我的gatsby-node.js文件:

const path = require('path');
const _ = require('lodash');

// Lifecycle methods

function attachFieldsToBlogPost({ node, actions }) {
  if (node.internal.type !== 'MarkdownRemark') {
    return;
  }

  const { createNodeField } = actions;

  const { slug, title } = node.frontmatter;
  const postPath = slug || _.kebabCase(title);

  createNodeField({
    node,
    name: 'slug',
    getter: node => node.frontmatter.slug, // eslint-disable-line no-shadow
    value: postPath,
  });

  createNodeField({
    node,
    name: 'url',
    value: postPath,
  });
}

exports.onCreateNode = function() { // eslint-disable-line func-names
  return Promise.all([attachFieldsToBlogPost].map(fn => fn.apply(this, arguments))); // eslint-disable-line prefer-rest-params
};

// Implementations

function getMarkdownQuery({ regex } = {}) {
  return `
    {
      allMarkdownRemark(
        sort: { fields: [frontmatter___date], order: DESC }
        filter: { fileAbsolutePath: { regex: "${regex}" } }
      ) {
        totalCount
        edges {
          node {
            fileAbsolutePath
            excerpt(pruneLength: 280)
            timeToRead
            frontmatter {
              title
              date
              slug
            }
            fields {
              url
              slug
            }
          }
        }
      }
    }
  `;
}

function createBlogPostPages({ edges, createPage }) {
  const component = path.resolve('src/templates/Post.js');

  edges.forEach(({ node }) => {
    const { slug, title } = node.frontmatter;
    const postPath = slug || _.kebabCase(title);

    createPage({
      path: postPath,
      component,
      context: {
        slug: postPath,
      },
    });
  });
}

exports.createPages = async({ actions, graphql }) => {
  const results = await Promise.all([
    graphql(getMarkdownQuery({ regex: '/src/posts/' })),
  ]);

  const error = results.filter(r => r.errors);
  if (error.length) {
    return Promise.reject(error[0].errors);
  }

  const [blogPostResults] = results;

  const { createPage } = actions;
  const blogPostEdges = blogPostResults.data.allMarkdownRemark.edges;

  createBlogPostPages({
    createPage,
    edges: blogPostEdges,
  });
};

我的示例博客文章内容是:

---
title: 'Hello world there'
date: '2018-08-25'
---

Here is some content.

```javascript
console.log('test')
```

当我提供slug时frontmatter 组件,页面按预期创建。但是,我只想使用 slug参数可用时(因此检查 frontmatter 是否在 attachFieldsToBlogPostcreateBlogPostPages 中都可用)。如果我删除 slug frontmatter 项目,我收到以下错误:

GraphQLError: Cannot query field "slug" on type "frontmatter".

有没有办法覆盖用于创建帖子页面的路径“如果”slug frontmatter 有吗?

希望这不是太模糊,因为这是我的第一个 Gatsby 项目,但看起来是一个非常有用的功能。谢谢!

最佳答案

如果您删除 slug 的所有情况,那么该字段将不再存在于 Gatsby 的内部架构中。您可能会遇到 the issue described here .

只要您至少有 1 个带有 slug 字段的 Markdown 文件,那么它将存在于 Gatsby 的自动化 GraphQL 模式中,然后您的条件逻辑应该可以工作。

关于javascript - GraphQL : Overriding slugs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51529382/

相关文章:

node.js - Nodejs 和 Streams - 详细概述?

javascript - react 上下文重新渲染提供者的每个 child ?

javascript - 搜索字符串中出现的单词列表?

javascript - Django模板: get dictionary's value based on the key that equals to certain tag's value

javascript - 具有单个失败回调的多个 ajax 调用

Eclipse调试器 "Failed to read variables"

javascript - span 元素内容::after 是什么意思?

node.js - 如何通过socket.io向离线/在线用户发送聊天通知?

reactjs - 如何使用 React JS 在每一行上呈现第 n 列?

javascript - reactJS - 如何在 Prop 内串联?