GraphQL: переопределение слагов

Я начинаю свой первый проект с Гэтсби и столкнулся с проблемой запроса данных, которые "могут" не всегда существовать. Вот мой 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 в обоих attachFieldsToBlogPost а также createBlogPostPages). Если я удалю slug элемент frontmatter, я получаю следующую ошибку:

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

Есть ли способ переопределить путь, используемый для создания страниц поста "если" slug frontmatter есть?

Надеюсь, это не слишком расплывчато, так как это мой первый проект Gatsby, но кажется довольно полезной функцией. Спасибо!

1 ответ

Решение

Если вы удалите каждый случай slug тогда поле больше не будет существовать во внутренней схеме Гэтсби. Вы, вероятно, сталкиваетесь с проблемой, описанной здесь.

Пока у вас есть по крайней мере 1 файл уценки с slug поле, тогда он будет существовать в автоматизированной схеме GraphQL Гэтсби, и тогда ваша условная логика должна работать.

Другие вопросы по тегам