Gatsby: Pertanyaan: Bagaimana cara membuat kueri berdasarkan nama sistem file gatsby-source?

Dibuat pada 27 Jul 2017  ·  20Komentar  ·  Sumber: gatsbyjs/gatsby

Saya memiliki banyak folder untuk jenis halaman yang berbeda. Yaitu. type1, type2, dll. yang berisi file penurunan harga.

pages
   --type1
   --type2

File di setiap folder diubah menggunakan gatsby-transformer-remark .
Saya hanya ingin menanyakan konten untuk tipe1, tipe2, dll.
Misalnya saya ingin halaman daftar type1 yang berisi daftar semua halaman 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',
      },
    },

Asumsi saya adalah Anda dapat melakukan kueri berdasarkan properti name .

Sesuatu seperti:

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

Saya mencoba semua pertanyaan yang berbeda seperti allSite dan allFile tetapi tidak dapat menemukan solusi.
Saya juga mencoba

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

yang sepertinya tidak mengembalikan sesuatu yang dapat saya gunakan untuk merender konten:

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

Bagaimana Anda melakukannya? Gunakan allFile dan filter berdasarkan nama path (yaitu regex yang cocok dengan folder type1 dan ekstensi penurunan harga)?

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

Komentar yang paling membantu

@ tsiq-swyx Saya menggunakan sesuatu seperti ini untuk meneruskan bidang collection dari File menjadi 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'),
    })

Pendekatan regex memang berhasil, tetapi itu rapuh.

Semua 20 komentar

Saya pikir Anda juga bisa memfilter jalur menggunakan 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
          }
        }
      }
    }
}

Node file memiliki nama instance sumber yang disetel sebagai sourceInstanceName sehingga Anda dapat menggunakannya untuk kueri.

Menggunakan regex adalah solusi yang bagus juga yang kami gunakan banyak di gatsbyjs.org misalnya.

BTW, jika Anda belum menggunakannya, GraphiQL sangat bagus untuk menjelajahi data apa yang tersedia.

@Kamamews Apakah ada cara untuk menggunakan sourceInstanceName dalam kueri allMarkdownRemark ? Saya berharap bisa mendapatkan sourceInstanceName dari file node untuk setiap node penurunan harga seperti ini, sehingga saya dapat memisahkan posting blog saya dari proyek saya tanpa menggunakan regex pada jalur file.

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

Tetapi debugger GraphQL menunjukkan bahwa sourceInstanceName tidak tersedia.

Bagaimana Anda merekomendasikan memfilter halaman penurunan harga berdasarkan jenis sumber, seperti proyek dan posting blog? Solusi saya saat ini untuk ini adalah mendapatkan fileAbsolutePath dari setiap node penurunan harga:

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

Dan kemudian untuk menguji apakah itu termasuk string tertentu, seperti /pages/blog/ atau /pages/projects/ . Tetapi ini akan rusak jika jalur absolut ke direktori situs gatsby itu sendiri berisi salah satu dari string ini. Apa yang Anda rekomendasikan sebagai praktik terbaik dalam kasus ini? (Maaf jika saya melewatkan sesuatu di dokumentasi.)

@nwshane cukup query allFile dan filter di sana. Anda dapat memfilter file penurunan harga dengan internal.mediaType .

@KAMAMAMews Bagaimana cara menggabungkan query pada allFile dengan sortir pada frontmatter? Apakah itu mungkin?

Mencoba mencari tahu sesuatu yang serupa.

Saya dapat memfilter menurut subfolder. Tapi saya tidak bisa melihat frontmatter di allFile .

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

MEMPERBARUI:

Ini berhasil untuk saya.

Saya memiliki folder posts dan pages di dalam folder content dan gatsby-config.js menunjuk ke 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 Sejak pembaruan terakhir saya, saya terjun ke sistem node sedikit lagi. Node allFile diurai oleh penangan penurunan harga dan kemudian node allMarkdownRemark dibuat. Jadi seperti yang Anda temukan, tidak mungkin mengurutkan menurut frontmatter dalam allFile karena ini hanya dihasilkan setelah parser penurunan harga masuk. Regex berfungsi, tetapi agak rapuh menurut selera saya. Solusi saya adalah menyalin nama koleksi (ditentukan dalam konfigurasi plugin sumber sistem file) dari node file ke node penurunan harga melalui hook onCreateNode . Tidak memiliki kode di depan saya untuk mengirim contoh, tetapi sangat cepat dan kemudian saya memiliki bidang di dalam allMarkdownRemark yang dapat saya filter.

Kemungkinan lain seperti yang disarankan @KAMAMews (dalam kasus saya, nama sumbernya adalah projects )

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

@gbouteiller Benar, itu akan mendapatkan frontmatter dan memungkinkan seseorang untuk memfilter dengan sourceInstanceName . Masalahnya adalah, Anda tidak dapat mengurutkan berdasarkan apa pun di dalam frontmatter menggunakan pendekatan ini. Sepertinya orang-orang membicarakan tentang entri blog di sini, dan biasanya diurutkan berdasarkan tanggal. Tanggal biasanya disimpan di dalam frontmatter .

Tidak ada cara untuk mengurutkan berdasarkan sesuatu dari frontmatter dan memfilter menurut sourceInstanceName secara default. sourceInstanceName tidak disalin dari simpul File ke dalam simpul markdownRemark . Satu-satunya pilihan adalah menggunakan regex atau menyalin beberapa data sesuai posting saya sebelumnya.

Jika pengurutan tidak diperlukan, yang mungkin benar dalam banyak kasus, pendekatan Anda sangat masuk akal. Saya tidak menyadari bahwa childMarkdownRemark tersedia sebagai bidang pada file , itu sangat berguna untuk diketahui, terima kasih telah berbagi.

memiliki masalah ini dan agak kecewa karena kolom "name" tidak berfungsi dengan baik dengan markdownRemark. adakah kemenangan kecil di sini yang dapat kami lakukan untuk meneruskan informasi ini?

EDIT: setelah mengotak-atik sedikit saya menyadari bahwa bidang id memperlihatkan jalur dan Anda dapat memfilter berdasarkan itu:

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
          }
        }
      }
    }
  }

bidang name dari sistem file sumber masih tidak benar-benar melakukan apa pun untuk komentar gatsby-transformer-, saya akan mengatakan itu meningkatkan dx sedikit untuk mengalirkannya sebagai bidang yang dapat ditanyakan / dapat disaring sejak gatsby-transformer-remark tidak pernah ada tanpa gatsby-source-filesystem .

@ tsiq-swyx Saya menggunakan sesuatu seperti ini untuk meneruskan bidang collection dari File menjadi 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'),
    })

Pendekatan regex memang berhasil, tetapi itu rapuh.

@chmac ini sangat pintar, dan berhasil, terima kasih telah membagikan solusi Anda. @KyleAMathews minta maaf telah menandai Anda (lmk jika ada orang lain untuk diberi tag) tetapi apakah mungkin gatsby-source-filesystem bekerja dengan cara ini (meneruskan sourceInstanceName ke bidang node atau bidang lain) secara default?

@ tsiq-swyx Saya tidak 100% yakin, tapi menurut saya ini mungkin permintaan tarik yang cukup sederhana! ;-)

Saya pikir pengelola gatsby memiliki pendapat yang kuat tentang hal-hal ini jadi saya pikir ada baiknya berdiskusi sebelum mengirim PR yang tidak diminta secara acak :)

Oke, saya berhasil, tetapi ekspor createPages saya hanya menggunakan satu template

Sangat menarik untuk melihat bahwa menggunakan gatsby-source-filesystem tidak membutuhkan AllFile di graphql sama sekali. Yang dapat menimbulkan kebingungan dan tidak tercermin dalam dokumentasi.
saya menggunakan
const { createPage } = actions const result = await graphql(` query { allMarkdownRemark { edges { node { fields { slug } frontmatter { lang } } } } } `)
dan itu membuat halaman tanpa masalah. Namun tidak yakin apakah prinsip yang sama berlaku untuk gatsby-source-git

Terima kasih @chac

Saya telah membuat halaman berdasarkan gatsby-source-filesystem nama ...

jadi inilah solusi saya:

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}`
    })
  }
}

Ini menarik, Tidak pernah ditemukan opsi seperti node.parent ada

Pada hari Senin, 27 April 2020, Noman Gul [email protected] menulis:

Terima kasih @chmac https://github.com/chmac

Saya telah membuat halaman berdasarkan nama sistem file gatsby-source ...

jadi inilah solusi saya:

const {createFilePath} = membutuhkan ("gatsby-source-filesystem")
exports.onCreateNode = ({node, actions, getNode}) => {
const {createNodeField} = tindakan

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

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

}
}

-
Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/gatsbyjs/gatsby/issues/1634#issuecomment-619670883 ,
atau berhenti berlangganan
https://github.com/notifications/unsubscribe-auth/AAEQPFX6KR7NUIY33Q7V4MDROTS7PANCNFSM4DUUPK6A
.

Saya berada dalam situasi yang sama yang menurut saya kasus yang cukup umum dan setelah membaca utas ini; solusi terbaik dan non-hacky, menurut saya, adalah:

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

Jenis konten projects ada di /content/projects/ .

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

magicly picture magicly  ·  3Komentar

KyleAMathews picture KyleAMathews  ·  3Komentar

Oppenheimer1 picture Oppenheimer1  ·  3Komentar

ghost picture ghost  ·  3Komentar

theduke picture theduke  ·  3Komentar