如何使用 Gatsby 显示图片和 markdown 文件的文件夹
Posted
技术标签:
【中文标题】如何使用 Gatsby 显示图片和 markdown 文件的文件夹【英文标题】:How to use Gatsby to display a folder of images and markdown files 【发布时间】: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
【问题讨论】:
【参考方案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 />
)
【讨论】:
以上是关于如何使用 Gatsby 显示图片和 markdown 文件的文件夹的主要内容,如果未能解决你的问题,请参考以下文章