لدي عدة مجلدات لأنواع صفحات مختلفة. بمعنى آخر. 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$/"}
}
) {...}
اعتقدت أنه يمكنك أيضًا تصفية المسار باستخدام 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
.
تحديث:
هذا عمل معي.
لدي مجلدات 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/
.
التعليق الأكثر فائدة
@ tsiq-swyx أستخدم شيئًا كهذا لتمرير الحقل
collection
منFile
إلىMarkdownRemark
.نهج
regex
ينجح ، لكنه هش.