У меня есть несколько папок для разных типов страниц. Т.е. 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 Есть ли способ использовать sourceInstanceName
в запросе allMarkdownRemark
? Я надеялся, что смогу получить 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
.
ОБНОВИТЬ:
Это сработало для меня.
У меня есть папки 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
невозможно выполнить сортировку по frontmatter, потому что он генерируется только после того, как сработает анализатор уценки. Регулярное выражение работает, но на мой вкус оно немного хрупкое. Мое решение состояло в том, чтобы скопировать имя коллекции (указанное в конфигурации плагина исходного кода файловой системы) из узла файла в узел уценки с помощью хука onCreateNode
. У меня нет кода для публикации примера, но это было очень быстро, а затем у меня есть поле внутри allMarkdownRemark
которому я могу фильтровать.
Другая возможность, как советовал @KyleAMathews (в моем случае имя источника - projects
)
allFile(filter: {internal: {mediaType: {eq: "text/markdown"}}, sourceInstanceName: {eq: "projects"}}) {
edges {
node {
childMarkdownRemark {
frontmatter {
...
}
}
}
}
}
@gbouteiller True, это получит frontmatter
и позволит фильтровать по sourceInstanceName
. Проблема в том, что вы не можете сортировать по чему-либо внутри frontmatter
используя этот подход. Кажется, здесь люди говорят о сообщениях в блогах, и они обычно сортируются по дате. Дата обычно хранится внутри frontmatter
.
Невозможно выполнить сортировку по чему-то из frontmatter
и фильтровать по sourceInstanceName
по умолчанию. sourceInstanceName
не копируется из узла File
узел markdownRemark
. Единственный вариант - использовать регулярное выражение или скопировать некоторые данные в соответствии с моей предыдущей публикацией.
Если сортировка не требуется, что может быть верным во многих случаях, тогда ваш подход имеет большой смысл. Я не понимал, что childMarkdownRemark
доступно как поле в file
, это очень полезно знать, спасибо, что поделились.
возникла эта проблема, и он был разочарован тем, что поле «name» не работает с markdownRemark. есть ли здесь небольшой выигрыш, который мы можем сделать, чтобы передать эту информацию?
EDIT: немного поработав, я понял, что поле 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-comment, я бы сказал, что оно немного улучшает 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, это очень умно и работает, спасибо, что поделились своим решением. @KyleAMathew извините за то, что пометил вас (lmk, если есть кто-то еще, чтобы пометить), но возможно ли, чтобы gatsby-source-filesystem
работал таким образом (передача sourceInstanceName в поле узла или другое поле) по умолчанию?
@ tsiq-swyx Я не уверен на 100%, но предполагаю, что это может быть довольно простой запрос на перенос! ;-)
Я думаю, что сопровождающие Gatsby имеют твердое мнение об этих вещах, поэтому я думаю, что стоит обсудить это перед отправкой случайных незапрашиваемых PR :)
Хорошо, у меня все заработало, но мой экспорт createPages использует только один шаблон
Интересно видеть, что использование gatsby-source-filesystem
вообще не требует AllFile в graphql. Что может ввести в заблуждение и не отражено в документации.
Я использую
const { createPage } = actions
const result = await graphql(`
query {
allMarkdownRemark {
edges {
node {
fields {
slug
}
frontmatter {
lang
}
}
}
}
}
`)
и он создает страницы без проблем. Однако не уверен, применим ли тот же принцип к gatsby-source-git
Спасибо @chmac
Мне нужно создавать страницы на основе gatsby-source-filesystem
name ...
так вот мое решение:
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
Мне нужно создавать страницы на основе имени исходной файловой системы gatsby ...
так вот мое решение:
const {createFilePath} = require ("исходная-файловая система gatsby")
export.onCreateNode = ({узел, действия, getNode}) => {
const {createNodeField} = действияif (node.internal.type ===
Mdx
&& getNode (node.parent) .sourceInstanceName === "карьера") {
значение 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
действительно работает, но он хрупкий.