ページタイプごとに複数のフォルダがあります。 つまり。 マークダウンファイルを含む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$/"}
}
) {...}
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
れません。
更新:
これは私のために働いた。
フォルダーposts
とpages
がフォルダーcontent
あり、 gatsby-config.js
がcontent
指しています。
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
デフォルトでは。 sourceInstanceName
はFile
ノードからmarkdownRemark
ノードにコピーされません。 唯一のオプションは、以前の投稿に従って、正規表現を使用するか、一部のデータをコピーすることです。
多くの場合に当てはまる可能性があるソートが不要な場合は、アプローチが非常に理にかなっています。 childMarkdownRemark
がfile
フィールドとして利用できることに気づいていませんでした。共有してくれてありがとう、知っておくととても便利です。
この問題が発生し、「名前」フィールドが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/
ます。
最も参考になるコメント
@ tsiq-swyxこのようなものを使用して、
collection
フィールドをFile
からMarkdownRemark
に渡します。regex
アプローチは機能しますが、壊れやすいものです。