Tengo varias carpetas para diferentes tipos de páginas. Es decir. type1, type2, etc., que contienen archivos de rebajas.
pages
--type1
--type2
Los archivos de cada carpeta se transforman usando gatsby-transformer-remark
.
Quiero consultar solo contenido para type1, type2, etc.
Por ejemplo, quiero una página de lista de tipo1 que contenga una lista de todas las páginas de tipo1.
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',
},
},
Mi suposición era que podría realizar consultas basadas en la propiedad name
.
Algo como:
{
someQueryForGatsbySourceFilesystem(
filter: {
name: {
eq: "type1"
}
}
) {
edges {
node {
childMarkdownRemark {
html
}
}
}
}
}
Intenté todas las consultas diferentes como allSite y allFile pero no pude encontrar una solución.
También lo intenté
allSitePlugin(filter: {
pluginOptions: {
name: {
eq: "type1"
}
}
})
que no parece devolver algo que pueda usar para renderizar contenido:
"Cannot query field \"childMarkdownRemark\" on type \"SitePlugin\".",
¿Como lo harias? ¿Usar allFile y filtrar según el nombre de la ruta (es decir, una expresión regular que coincida con la carpeta type1
y la extensión de descuento)?
allFile(
filter: {
absolutePath:{regex:"/(type1)\/.*\\.md$/"}
}
) {...}
Pensé que también podrías filtrar la ruta usando 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
}
}
}
}
}
Los nodos de archivo tienen el nombre de la instancia de origen establecido como sourceInstanceName
por lo que puede usarlo para consultas.
Usar expresiones regulares también es una gran solución que usamos mucho en gatsbyjs.org, por ejemplo.
Por cierto, si aún no lo está utilizando, GraphiQL es excelente para explorar qué datos están disponibles.
@KyleAMathews ¿Hay alguna forma de usar sourceInstanceName
en la consulta allMarkdownRemark
? Esperaba poder obtener el sourceInstanceName
del nodo de archivo para cada nodo de rebajas como este, para poder separar las publicaciones de mi blog de mis proyectos sin usar expresiones regulares en las rutas del archivo.
{
allMarkdownRemark {
edges {
node {
sourceInstanceName
}
}
}
}
Pero el depurador GraphQL muestra que sourceInstanceName
no está disponible.
¿Cómo recomiendas filtrar las páginas de rebajas por tipo de fuente, como proyectos y publicaciones de blog? Mi solución actual para esto es obtener el fileAbsolutePath
de cada nodo de rebajas:
{
allMarkdownRemark {
edges {
node {
fileAbsolutePath
}
}
}
}
Y luego para probar si incluye ciertas cadenas, como /pages/blog/
o /pages/projects/
. Pero esto se romperá si la ruta absoluta al directorio del sitio gatsby contiene una de estas cadenas. ¿Qué recomienda como mejor práctica en este caso? (Lo siento si me perdí algo en la documentación).
@nwshane solo consulta allFile
y filtra allí. Puede filtrar los archivos de rebajas por internal.mediaType
.
@KyleAMathews ¿Cómo se combina una consulta en allFile
con una ordenación en frontmatter? ¿Es eso posible?
Tratando de averiguar algo similar.
Puedo filtrar por subcarpeta. Pero no puedo ver frontmatter
en allFile
.
ACTUALIZAR:
Esto funcionó para mí.
Tengo carpetas posts
y pages
dentro de la carpeta content
y mi gatsby-config.js
apunta a 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 Desde mi última actualización, me allFile
son analizados por el controlador de rebajas y luego se crean nuevos nodos allMarkdownRemark
. Entonces, como descubrió, no es posible ordenar por frontmatter en allFile
porque solo se genera una vez que se activa el analizador de rebajas. La expresión regular funciona, pero es un poco frágil para mi gusto. Mi solución fue copiar el nombre de la colección (especificado en la configuración del complemento de origen del sistema de archivos) desde el nodo del archivo al nodo de rebajas a través de un gancho onCreateNode
. No tengo el código delante para publicar un ejemplo, pero fue muy rápido y luego tengo un campo dentro de allMarkdownRemark
que puedo filtrar.
Otra posibilidad como aconsejó @KyleAMathews (en mi caso, el nombre de la fuente es projects
)
allFile(filter: {internal: {mediaType: {eq: "text/markdown"}}, sourceInstanceName: {eq: "projects"}}) {
edges {
node {
childMarkdownRemark {
frontmatter {
...
}
}
}
}
}
@gbouteiller Cierto, obtendrá el frontmatter
y permitirá filtrar por sourceInstanceName
. El problema es que no puede ordenar por nada dentro de frontmatter
usando este enfoque. Parece que la gente está hablando de publicaciones de blog aquí, y generalmente están ordenadas por fecha. La fecha normalmente se almacena dentro de frontmatter
.
No hay forma de ordenar por algo de frontmatter
y filtrar por sourceInstanceName
de forma predeterminada. El sourceInstanceName
no se copia del nodo File
en el nodo markdownRemark
. La única opción es usar una expresión regular o copiar algunos datos según mi publicación anterior.
Si no se requiere la clasificación, lo que puede ser cierto en muchos casos, entonces su enfoque tiene mucho sentido. No me había dado cuenta de que childMarkdownRemark
estaba disponible como un campo en file
, es muy útil saberlo, gracias por compartir.
tuvo este problema y me decepcionó un poco que el campo "nombre" no funcione bien con el markdownRemark. ¿Hay alguna pequeña victoria aquí que podamos hacer para transmitir esta información?
EDITAR: después de jugar un poco, me di cuenta de que el campo de identificación expone la ruta y puede filtrar en función de eso:
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
}
}
}
}
}
el campo name
del sistema de archivos fuente todavía no hace nada para gatsby-transformer-comment, yo diría que mejora un poco el dx para que fluya como un campo consultable / filtrable ya que gatsby-transformer-remark
nunca existe sin gatsby-source-filesystem
.
@ tsiq-swyx Estoy usando algo como esto para pasar el campo collection
de File
a 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'),
})
El enfoque regex
funciona, pero es frágil.
@chmac esto es muy inteligente y funciona, gracias por compartir su solución. @KyleAMathews lo siento por etiquetarte (lmk si hay alguien más para etiquetar) pero ¿es posible que gatsby-source-filesystem
funcione de esta manera (pasando sourceInstanceName a un campo de nodo o algún otro campo) por defecto?
@ tsiq-swyx No estoy 100% seguro, ¡pero me imagino que podría ser una solicitud de extracción bastante simple! ;-)
Creo que los mantenedores de Gatsby tienen opiniones sólidas sobre estas cosas, así que creo que vale la pena discutirlo antes de enviar PR no solicitadas al azar :)
De acuerdo, lo hice funcionar, pero mi exportación de createPages solo usa una plantilla
Es interesante ver que usar gatsby-source-filesystem
no requiere AllFile en graphql en absoluto. Lo que puede generar confusión y no se refleja en la documentación.
estoy usando
const { createPage } = actions
const result = await graphql(`
query {
allMarkdownRemark {
edges {
node {
fields {
slug
}
frontmatter {
lang
}
}
}
}
}
`)
y crea páginas sin problemas. Sin embargo, no estoy seguro si se aplica el mismo principio a gatsby-source-git
Gracias @chmac
Tengo que crear páginas basadas en el gatsby-source-filesystem
name ...
así que aquí está mi solución:
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}`
})
}
}
Esto es interesante, nunca encontré tal opción node.parent existe
El lunes 27 de abril de 2020, Noman Gul [email protected] escribió:
Gracias @chmac https://github.com/chmac
Tengo que crear páginas basadas en el nombre de gatsby-source-filesystem ...
así que aquí está mi solución:
const {createFilePath} = require ("gatsby-source-filesystem")
export.onCreateNode = ({nodo, acciones, getNode}) => {
const {createNodeField} = accionesif (node.internal.type ===
Mdx
&& getNode (node.parent) .sourceInstanceName === "carreras") {
valor constante = createFilePath ({nodo, getNode})createNodeField({ name: "slug", node, value: `/careers${value}` })
}
}-
Estás recibiendo esto porque comentaste.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/gatsbyjs/gatsby/issues/1634#issuecomment-619670883 ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/AAEQPFX6KR7NUIY33Q7V4MDROTS7PANCNFSM4DUUPK6A
.
Estoy en la misma situación que creo que es un caso bastante común y después de leer este hilo; La mejor solución y no pirata, en mi opinión, es:
{
allMarkdownRemark(filter: {fileAbsolutePath: {regex: "/projects/"}}) {
edges {
node {
frontmatter {
title
}
}
}
}
}
Mi tipo de contenido projects
está en /content/projects/
.
Comentario más útil
@ tsiq-swyx Estoy usando algo como esto para pasar el campo
collection
deFile
aMarkdownRemark
.El enfoque
regex
funciona, pero es frágil.