【问题标题】:How to use Gatsby to display a folder of images and markdown files如何使用 Gatsby 显示图片和 markdown 文件的文件夹
【发布时间】:2021-03-04 05:37:23
【问题描述】:

所以我对 Gatsby、react、GraphQL 等非常陌生。过去我使用纯 CSS、HTML 和 javascript 来制作我的网站。虽然,我对盖茨比和它的功能很感兴趣,所以我决定挑战自己并学习它。

我正在为自己建立一个投资组合网站,并且为了便于更新,我希望能够通过创建新文件夹、运行构建脚本并将构建的站点放入我的 FTP 来添加新项目。

这就是我的项目文件夹结构的设置方式:

-src
--projects
---1-daido-moriyama
----1-dm-frontcover.jpg
----2-dm-spread.jpg
----3-dm-backcover.jpg
----project-metadata.md
[...]
---2-lunch-from-a-care-package
----1-lf-wordmark.png
----2-lf-logo.png
----3-lf-poster.jpg
----project-metadata.md
[...]

该站点是一个页面,因此无需为每个项目创建新页面。我只是将它们分类到编号的文件夹中,因为这对我自己来说是最容易更新的。

理想情况下,我想从每个项目的 markdown 文件中获取标题和描述,并将标题放在 h3 中,将描述放在 ap 中,然后将图像显示在 div 中,样式化后将成为轮播。

Mockup of the design

My current progress

我一直在运行一些测试,并且能够使用 allMarkdownRemark 访问降价文件,并使用 allImageSharp 访问图像。这很 hacky,但它有效,唯一的问题是它显示了 所有 图像,而不仅仅是每个项目所需的图像。比如说,我在一个项目中有 8 张图片,在另一个项目中有 5 张,它将显示所有 13 张图片。

有没有办法做我想要对 Gatsby 做的事情?还是我应该放弃并回到杰基尔……

gatsby-config.js:

module.exports = {
  siteMetadata: {
    title: 'J.C.R.'
  },
  plugins: [
    'gatsby-plugin-react-helmet',
    'gatsby-plugin-sass',
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'projects',
        path: `${__dirname}/src/projects/`
      }
    },
    'gatsby-transformer-remark',
    'gatsby-transformer-sharp',
    'gatsby-plugin-sharp',
    `@dream-bit-de/gatsby-plugin-better-page-tree`
  ]
}

gatsby-node.js:

const path = require('path')

module.exports.onCreateNode = ({ node, actions}) => {
    const {createNodeField} = actions

    if (node.internal.type === 'MarkdownRemark') {
        const slug = path.basename(path.dirname(node.fileAbsolutePath, '.md'))
        createNodeField({
            node,
            name: 'slug',
            value: slug
        })
    }
}

工作组件:

import React from 'react'
import { graphql, useStaticQuery } from 'gatsby'
import Img from 'gatsby-image'

const Work = () => {
    const data = useStaticQuery(graphql`
        query {
            allMarkdownRemark(
                sort: { order: ASC, fields: [frontmatter___position]}
            ) {
            edges {
                node {
                    frontmatter {
                        title
                        description
                    }
                    fields {
                        slug
                    }
                }
            }
            }
            allFile (
            filter: { 
                ext: {eq: ".jpg"}
            },
            sort: { 
                order: ASC, 
                fields: [relativePath]
            }
            ) {
                edges {
                node {
                    relativePath
                    relativeDirectory
                    name
                    ext
                    id
                    base
                }
            }
            }
        }
    `)

    console.log(data)
    return (
        <div id="work">
            <ol>
                {data.allMarkdownRemark.edges.map((edge) => {
                    return (
                        <li class={edge.node.fields.slug}>
                            <h3>{edge.node.frontmatter.title}</h3>
                            <p>{edge.node.frontmatter.description}</p>
                            {data.allFile.edges.map((edge) => {
                                return (
                                    <img src={`../projects${edge.node.relativeDirectory}/${edge.node.name}-${edge.node.base}${edge.node.ext}`}></img>
                                )
                            })}
                        </li>
                    )
                })}
            </ol>
        </div>
    )
}

export default Work

index.js:

import React from 'react'
import Head from '../components/head'
import Info from '../components/info'
import Work from '../components/work'
import '../styles/index.scss'

const indexPage = () => {
  return (
    <div>
      <Head/>
      <Info/>
      <Work/>
    </div>
  )
}

export default indexPage

【问题讨论】:

    标签: node.js reactjs graphql gatsby


    【解决方案1】:

    我应该深入研究项目以充分了解如何直接使用 graphql 查询来处理它,但一个简短的解决方法是过滤掉与项目无关的图像。

     {data.allFile.edge0s.filter((item) => item.name.includes(edge.node.frontmatter.id).map((edge) => {
        return (
       <img src={`../projects${edge.node.relativeDirectory}/${edge.node.name}-${edge.node.base}${edge.node.ext}`}></img>
    )
    })}
    

    您需要在与项目相关的文件的名称上添加一个特定的 ID,以便在获取它们时过滤掉不相关的文件。

    为了更好,您可以格式化您的 imageSchema 并添加一个特定的属性来处理这种情况,这样您就不需要格式化图像名称,然后您可以使用 item.myProperty === 而不是 .includes() myCustomSchemaProperty。

    【讨论】:

      【解决方案2】:

      这比您迄今为止尝试的要容易得多。我建议使用gatsby-image,因为当您添加以下内容时,所有图像都属于 Gatsby 生态系统:

      {
        resolve: 'gatsby-source-filesystem',
        options: {
          name: 'projects',
          path: `${__dirname}/src/projects/`
        }
      },
      

      Gatsby 将在内部解析 /src/projects/ 中的所有内容,并创建节点以使架构可用于 GraphQL,因此:

      {
        allFile(filter: {extension: {eq: "jpg"}}) {
          edges {
            node {
              childImageSharp{
                fluid{
                  ...GatsbyImageSharpFluid
                }
              }
            }
          }
        }
      }
      

      然后在你的组件中:

      {data.allFile.edges.map((edge) => {
         return <Img fluid={edge.childImageSharp.fluid} />
      })}
      

      【讨论】:

        猜你喜欢
        • 2023-03-14
        • 2021-11-06
        • 1970-01-01
        • 2017-04-17
        • 1970-01-01
        • 2021-03-10
        • 2013-11-18
        • 1970-01-01
        • 2012-03-18
        相关资源
        最近更新 更多