Gatsby: السؤال: كيف يمكنني الاستعلام بناءً على اسم نظام ملفات gatsby-source-files؟

تم إنشاؤها على ٢٧ يوليو ٢٠١٧  ·  20تعليقات  ·  مصدر: gatsbyjs/gatsby

لدي عدة مجلدات لأنواع صفحات مختلفة. بمعنى آخر. type1 ، type2 ، إلخ. التي تحتوي على ملفات markdown.

pages
   --type1
   --type2

يتم تحويل الملفات في كل مجلد باستخدام gatsby-transformer-remark .
أرغب في الاستعلام فقط عن محتوى للنوع 1 ، النوع 2 ، إلخ.
على سبيل المثال ، أريد صفحة قائمة من النوع 1 تحتوي على قائمة بجميع صفحات النوع 1.

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 والتصفية استنادًا إلى اسم المسار (مثل regex الذي يتطابق مع المجلد type1 وامتداد markdown)؟

 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 حتى تتمكن من استخدامه للاستعلامات.

يعد استخدام regex حلاً رائعًا أيضًا نستخدمه كثيرًا على gatsbyjs.org على سبيل المثال.

راجع للشغل ، إذا لم تكن تستخدمه بالفعل ، فإن GraphiQL رائعة لاستكشاف البيانات المتاحة.

KyleAMathews هل هناك طريقة لاستخدام sourceInstanceName في الاستعلام allMarkdownRemark ؟ كنت آمل أن أحصل على sourceInstanceName لعقدة الملف لكل عقدة تخفيض مثل هذه ، حتى أتمكن من فصل منشورات مدونتي عن مشاريعي دون استخدام regex في مسارات الملفات.

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

لكن مصحح GraphQL يوضح أن sourceInstanceName غير متوفر.

كيف توصي بتصفية صفحات التخفيض حسب نوع المصدر ، مثل المشاريع ومنشورات المدونة؟ الحل الحالي لهذا هو الحصول على fileAbsolutePath لكل عقدة تخفيض السعر:

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

ثم لاختبار ما إذا كان يتضمن سلاسل معينة ، مثل /pages/blog/ أو /pages/projects/ . ولكن هذا سوف ينقطع إذا كان المسار المطلق إلى دليل موقع gatsby نفسه يحتوي على أحد هذه السلاسل. بماذا تنصح كأفضل ممارسة في هذه الحالة؟ (آسف إذا فاتني شيء ما في الوثائق.)

nwshane فقط allFile وقم بالتصفية هناك. يمكنك تصفية ملفات التخفيض بمقدار internal.mediaType .

KyleAMathews كيف يمكن للمرء أن يجمع استعلامًا على allFile مع نوع على المادة الأولى؟ هل هذا ممكن؟

أحاول اكتشاف شيء مشابه.

يمكنني التصفية حسب المجلد الفرعي. لكن لا يمكنني رؤية frontmatter في allFile .

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

تحديث:

هذا عمل معي.

لدي مجلدات 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 بواسطة معالج markdown ثم يتم إنشاء عقد allMarkdownRemark . لذا كما وجدت ، ليس من الممكن الفرز حسب المادة الأمامية في allFile لأنه يتم إنشاؤه فقط بمجرد بدء محلل تخفيض السعر. يعمل regex ، لكنه هش قليلاً بالنسبة لذوقي. كان الحل هو نسخ اسم المجموعة (المحدد في تكوين البرنامج المساعد لمصدر نظام الملفات) من عقدة الملف إلى عقدة markdown عبر ربط onCreateNode . ليس لدي الرمز أمامي لنشر مثال ، ولكنه كان سريعًا جدًا وبعد ذلك لدي حقل داخل allMarkdownRemark يمكنني التصفية من خلاله.

احتمال آخر كما نصح KyleAMathews (في حالتي ، اسم المصدر هو projects )

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

gbouteiller صحيح ، سيؤدي ذلك إلى الحصول على frontmatter والسماح للمرء بالتصفية بمقدار sourceInstanceName . المشكلة هي أنه لا يمكنك الفرز حسب أي شيء داخل frontmatter باستخدام هذا الأسلوب. يبدو أن الناس يتحدثون عن منشورات المدونة هنا ، وعادةً ما يتم فرزهم حسب التاريخ. يتم تخزين التاريخ عادة داخل frontmatter .

لا توجد طريقة للقيام بالفرز حسب شيء من frontmatter والتصفية حسب sourceInstanceName افتراضيًا. و sourceInstanceName لم يتم نسخ من File العقدة في markdownRemark العقدة. الخيار الوحيد هو استخدام regex أو نسخ بعض البيانات حسب رسالتي السابقة.

إذا لم يكن الفرز مطلوبًا ، وهو ما قد يكون صحيحًا في كثير من الحالات ، فإن أسلوبك سيكون منطقيًا للغاية. لم أكن أدرك أن childMarkdownRemark كان متاحًا كحقل على file ، من المفيد جدًا معرفة ذلك ، شكرًا للمشاركة.

هذه المشكلة إلى وكان نوعًا من خيبة الأمل لأن حقل "الاسم" لا يعمل بشكل جيد مع markdownRemark. هل هناك مكسب صغير هنا يمكننا القيام به لتمرير هذه المعلومات؟

تحرير: بعد العبث قليلاً ، أدركت أن حقل المعرف يعرض المسار ويمكنك التصفية بناءً على ذلك:

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 ، وأود أن أقول إنه يحسن dx قليلاً لتدفق ذلك من خلاله كحقل قابل للاستعلام / قابل للتصفية منذ gatsby-transformer-remark أبدًا موجود بدون 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٪ ، لكني أتخيل أنه قد يكون طلب سحب بسيطًا إلى حد ما! ؛-)

أعتقد أن مديري خدمة gatsby لديهم آراء قوية حول هذه الأشياء ، لذا أعتقد أن الأمر يستحق المناقشة قبل إرسال رسائل ترويجية عشوائية غير مرغوب فيها :)

حسنًا ، لقد نجحت ، لكن تصدير createPages الخاص بي يستخدم نموذجًا واحدًا فقط

من المثير للاهتمام أن نرى أن استخدام gatsby-source-filesystem لا يتطلب 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 ، كتب نعمان جول [email protected] :

شكرا chmac https://github.com/chmac

يجب أن أقوم بإنشاء صفحات بناءً على اسم نظام ملفات جاتسبي المصدر ...

إذن هذا هو الحل:

const {createFilePath} = تتطلب ("gatsby-source-filesystem")
export.onCreateNode = ({عقدة ، إجراءات ، getNode}) => {
const {createNodeField} = إجراءات

if (node.internal.type === Mdx && getNode (node.parent) .sourceInstanceName === "Careers") {
قيمة const = createFilePath ({عقدة ، 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 التقييمات

القضايا ذات الصلة

andykais picture andykais  ·  3تعليقات

mikestopcontinues picture mikestopcontinues  ·  3تعليقات

kalinchernev picture kalinchernev  ·  3تعليقات

benstr picture benstr  ·  3تعليقات

totsteps picture totsteps  ·  3تعليقات