Gatsby: 質問:gatsby-source-filesystem名に基づいてクエリを実行するにはどうすればよいですか?

作成日 2017年07月27日  ·  20コメント  ·  ソース: gatsbyjs/gatsby

ページタイプごとに複数のフォルダがあります。 つまり。 マークダウンファイルを含むtype1、type2など。

pages
   --type1
   --type2

各フォルダー内のファイルは、 gatsby-transformer-remarkを使用して変換されます。
type1、type2などのコンテンツのみをクエリしたい。
たとえば、すべてのtype1ページのリストを含むtype1リストページが必要です。

gatsby-config.js

   {
      resolve: 'gatsby-source-filesystem',
      options: {
        path: `${__dirname}/src/pages/type1`,
        name: 'type1',
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        path: `${__dirname}/src/pages/type2`,
        name: 'type2',
      },
    },

私の仮定は、 nameプロパティに基づいてクエリを実行できるというものでした。

何かのようなもの:

{
  someQueryForGatsbySourceFilesystem(
    filter: {
      name: {
        eq: "type1"
      }
    }
  ) {
    edges {
      node {
        childMarkdownRemark {
          html
        }
      }
    }
  }
}

allSiteやallFileなど、さまざまなクエリをすべて試しましたが、解決策が見つかりませんでした。
私も試しました

  allSitePlugin(filter: {
    pluginOptions: {
      name: {
        eq: "type1"
      }
    }
  })

これは、コンテンツのレンダリングに使用できるものを返さないようです。

"Cannot query field \"childMarkdownRemark\" on type \"SitePlugin\".",

どうしますか? allFileを使用し、パス名(つまり、フォルダーtype1とマークダウン拡張子に一致する正規表現)に基づいてフィルター処理しますか?

 allFile(
  filter: {
    absolutePath:{regex:"/(type1)\/.*\\.md$/"}
  }
) {...}
question or discussion

最も参考になるコメント

@ tsiq-swyxこのようなものを使用して、 collectionフィールドをFileからMarkdownRemarkに渡します。

exports.onCreateNode = ({ node, boundActionCreators, getNode }) => {
  const { createNodeField } = boundActionCreators

  if (_.get(node, 'internal.type') === `MarkdownRemark`) {
    // Get the parent node
    const parent = getNode(_.get(node, 'parent'))

    // Create a field on this node for the "collection" of the parent
    // NOTE: This is necessary so we can filter `allMarkdownRemark` by
    // `collection` otherwise there is no way to filter for only markdown
    // documents of type `post`.
    createNodeField({
      node,
      name: 'collection',
      value: _.get(parent, 'sourceInstanceName'),
    })

regexアプローチは機能しますが、壊れやすいものです。

全てのコメント20件

allMarkdownRemarkを使用してパスをフィルタリングすることもできると思いました:

{
   allMarkdownRemark(
    sort: { order: DESC, fields: [frontmatter___date]},
    filter: {fileAbsolutePath: {regex: "/(type1)/.*\\.md$/"}}
  ) {
      edges {
        node {
          excerpt(pruneLength: 250)
          id
          frontmatter {
            title
            date(formatString: "MMMM DD, YYYY")
            path
          }
        }
      }
    }
}

ファイルノードのソースインスタンス名はsourceInstanceName設定されているため、クエリに使用できます。

正規表現の使用も優れたソリューションであり、たとえばgatsbyjs.orgで多く使用されています。

ところで、まだ使用していない場合、GraphiQLは利用可能なデータを調べるのに最適です。

@KyleAMathews allMarkdownRemarkクエリでsourceInstanceNameを使用する方法はありますか? このように各マークダウンノードのファイルノードのsourceInstanceNameを取得できることを期待していたので、ファイルパスに正規表現を使用せずにブログ投稿をプロジェクトから分離できます。

{
  allMarkdownRemark {
    edges {
      node {
        sourceInstanceName
      }
    }
  }
}

しかし、GraphQLデバッガーは、 sourceInstanceNameが使用できないことを示しています。

プロジェクトやブログ投稿などのソースタイプでマークダウンページをフィルタリングすることをどのように推奨しますか? これに対する私の現在の解決策は、各マークダウンノードのfileAbsolutePathを取得することです。

{
  allMarkdownRemark {
    edges {
      node {
        fileAbsolutePath
      }
    }
  }
}

次に、 /pages/blog//pages/projects/などの特定の文字列が含まれているかどうかをテストします。 ただし、gatsbyサイトディレクトリ自体への絶対パスにこれらの文字列のいずれかが含まれている場合、これは機能しなくなります。 この場合のベストプラクティスとして何をお勧めしますか? (ドキュメントで何かを見逃してしまった場合は申し訳ありません。)

@nwshaneはallFileをクエリし、そこでフィルタリングします。 internal.mediaTypeでマークダウンファイルをフィルタリングできます。

@KyleAMathews allFileクエリとfrontmatterの並べ替えをどのように組み合わせるのですか? それは可能ですか?

似たようなものを見つけようとしています。

サブフォルダでフィルタリングできます。 しかし、 allFile frontmatterれません。

screen shot 2018-02-25 at 8 18 51 p m

更新:

これは私のために働いた。

フォルダーpostspagesがフォルダーcontentあり、 gatsby-config.jscontent指しています。

export const query = graphql`
  query IndexQuery {
    allMarkdownRemark(
      filter: { fileAbsolutePath: {regex : "\/posts/"} },
      sort: {fields: [frontmatter___date], order: DESC},
    ) {
      totalCount
      edges {
        node {
          id
          frontmatter {
            title
            slug
            date(formatString: "DD MMMM YYYY")
            category
          }
          excerpt
        }
      }
    }
  }
`;

@lukejanicke前回の更新以来、ノードシステムについてもう少し詳しく説明しました。 allFileノードはマークダウンハンドラーによって解析され、新しいallMarkdownRemarkノードが作成されます。 ご覧のとおり、 allFileフロントマターで並べ替えることはできません。これは、マークダウンパーサーが起動したときにのみ生成されるためです。正規表現は機能しますが、私の好みでは少し壊れやすいです。 私の解決策は、コレクション名(ファイルシステムソースプラグインの構成で指定)をファイルノードからonCreateNodeフックを介してマークダウンノードにコピーすることallMarkdownRemark内にフィルターできるフィールドがあります。

@KyleAMathewsがアドバイスした別の可能性(私の場合、ソース名はprojects

allFile(filter: {internal: {mediaType: {eq: "text/markdown"}}, sourceInstanceName: {eq: "projects"}}) {
  edges {
    node {
      childMarkdownRemark {
        frontmatter {
            ...
        }
      }
    }
  }
}

@gbouteiller、それが取得しますfrontmatterとすることにより、フィルタに1を許可するsourceInstanceName 。 問題は、このアプローチを使用してfrontmatter内の何でもソートできないことです。 人々はここでブログ投稿について話しているようで、それらは通常日付でソートされています。 日付は通常、 frontmatter内に保存されます。

何かによってソート実行する方法はありませんfrontmatterによって、フィルターsourceInstanceNameデフォルトでは。 sourceInstanceNameFileノードからmarkdownRemarkノードにコピーされません。 唯一のオプションは、以前の投稿に従って、正規表現を使用するか、一部のデータをコピーすることです。

多くの場合に当てはまる可能性があるソートが不要な場合は、アプローチが非常に理にかなっています。 childMarkdownRemarkfileフィールドとして利用できることに気づいていませんでした。共有してくれてありがとう、知っておくととても便利です。

この問題が発生し、「名前」フィールドがmarkdownRemarkでうまく機能しないことに少しがっかりしました。 この情報を伝えるために私たちができる小さな勝利はここにありますか?

編集:少しいじった後、idフィールドがパスを公開し、それに基づいてフィルタリングできることに気付きました:

query AllQuery {
    DSes: allMarkdownRemark(
      limit: 3
      filter: { id: { regex: "/_design-systems/" } }
    ) {
      edges {
        node {
          frontmatter {
            title
            date
            company
            link
            image
            description
          }
          fields {
            slug
          }
        }
      }
    }

    Articles: allMarkdownRemark(
      limit: 3
      filter: { id: { regex: "/_articles/" } }
    ) {
      edges {
        node {
          frontmatter {
            title
            date
            company
            link
            image
            description
          }
          fields {
            slug
          }
        }
      }
    }
  }

ソースファイルシステムのnameフィールドは、gatsby-transformer-remarkに対してはまだ実際には何もしません。 gatsby-transformer-remarkは決してないので、クエリ可能/フィルタリング可能なフィールドとしてそれを流すためにdxを少し改善すると思います。 gatsby-source-filesystemなしで存在します。

@ tsiq-swyxこのようなものを使用して、 collectionフィールドをFileからMarkdownRemarkに渡します。

exports.onCreateNode = ({ node, boundActionCreators, getNode }) => {
  const { createNodeField } = boundActionCreators

  if (_.get(node, 'internal.type') === `MarkdownRemark`) {
    // Get the parent node
    const parent = getNode(_.get(node, 'parent'))

    // Create a field on this node for the "collection" of the parent
    // NOTE: This is necessary so we can filter `allMarkdownRemark` by
    // `collection` otherwise there is no way to filter for only markdown
    // documents of type `post`.
    createNodeField({
      node,
      name: 'collection',
      value: _.get(parent, 'sourceInstanceName'),
    })

regexアプローチは機能しますが、壊れやすいものです。

@chmacこれは非常に賢く、機能します。ソリューションを共有していただきありがとうございます。 @KyleAMathewsタグ付けして申し訳ありませんが(タグ付けする人が他にいる場合はlmk)、デフォルトでgatsby-source-filesystemがこのように機能する(sourceInstanceNameをノードフィールドまたは他のフィールドに渡す)ことは可能ですか?

@ tsiq-swyx 100%確信はありませんが、かなり単純なプルリクエストかもしれないと思います! ;-)

ギャツビーのメンテナはこれらのことについて強い意見を持っていると思うので、ランダムな一方的なPRを送信する前に議論する価値があると思います:)

動作しましたが、createPagesエクスポートでは1つのテンプレートしか使用しません

gatsby-source-filesystemを使用するのに、graphqlのAllFileがまったく必要ないことは興味深いことです。 これは混乱を招く可能性があり、ドキュメントには反映されていません。
使ってます
const { createPage } = actions const result = await graphql(` query { allMarkdownRemark { edges { node { fields { slug } frontmatter { lang } } } } } `)
そしてそれは問題なくページを作成します。 ただし、同じ原則がgatsby-source-git適用されるかどうかはわかりません

ありがとう@chmac

gatsby-source-filesystem名前に基づいてページを作成する必要があります...

だからここに私の解決策があります:

const { createFilePath } = require("gatsby-source-filesystem")

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  if (node.internal.type === `Mdx` && getNode(node.parent).sourceInstanceName === "careers") {
    const value = createFilePath({ node, getNode })

    createNodeField({
      name: "slug",
      node,
      value: `/careers${value}`
    })
  }
}

これは興味深いです、そのようなオプションnode.parentが存在することはありません

月曜日、27日に2020年4月には、NOMANギュル[email protected]書きました:

ありがとう@chmachttps ://github.com/chmac

gatsby-source-filesystem名に基づいてページを作成する必要があります...

だからここに私の解決策があります:

const {createFilePath} = require( "gatsby-source-filesystem")
exports.onCreateNode =({node、actions、getNode})=> {
const {createNodeField} =アクション

if(node.internal.type === Mdx && getNode(node.parent).sourceInstanceName === "careers"){
const value = createFilePath({node、getNode})

createNodeField({
  name: "slug",
  node,
  value: `/careers${value}`
})

}
}


あなたがコメントしたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/gatsbyjs/gatsby/issues/1634#issuecomment-619670883
または購読を解除する
https://github.com/notifications/unsubscribe-auth/AAEQPFX6KR7NUIY33Q7V4MDROTS7PANCNFSM4DUUPK6A

私は、このスレッドを読んだ後、かなり一般的なケースだと思うのと同じ状況にあります。 私の意見では、ハッキーではない最善の解決策は次のとおりです。

{
  allMarkdownRemark(filter: {fileAbsolutePath: {regex: "/projects/"}}) {
    edges {
      node {
        frontmatter {
          title
        }
      }
    }
  }
}

私のprojectsタイプのコンテンツは/content/projects/ます。

このページは役に立ちましたか?
0 / 5 - 0 評価

関連する問題

totsteps picture totsteps  ·  3コメント

benstr picture benstr  ·  3コメント

brandonmp picture brandonmp  ·  3コメント

kalinchernev picture kalinchernev  ·  3コメント

dustinhorton picture dustinhorton  ·  3コメント