所以我在Gatsby和Remark上写了一个博客网站。我的帖子结构如下:
Library/
-- category-name/
---- article-name/
------ index.md
这确实非常有效,使我能够进行类似/category-name/article-name
的路径。
我还想做的是能够在其中放置一个名为“ hero.jpg”的图像,并让盖茨比自动将其拾取,而不必为其添加前题参考。
到目前为止,我已经成功地通过将以下内容添加到“ gatsby-node.js”中来做到这一点:
const hero = (fs.existsSync(path.resolve(__dirname, `src/library/pages/${slug}hero.jpg`))) ? `${slug}hero.jpg` : ''
createNodeField({
node,
name: 'hero',
value: hero,
})
这在graphql数据范围内一直有效,现在我看到以下内容:
{
"node": {
"id": "3190922a-2207-5621-a7be-e02be9e8da24",
"fields": {
"hero": "/category-name/article-name/hero.jpg"
},
},
但是,在实际页面上,图像链接/category-name/article-name/hero.jpg
不存在,所以我得到了无效的图像。我知道这是因为gatsby-transformer-sharp
正在转换我的图像路径,但是我不知道如何确定它要转换为什么。
我认为我需要对this SO question做一些回答,但这似乎希望您知道relativePath
是在您编写查询时,但是我没有该信息,直到查询第一次返回为止。
添加了OnCreateNode钩子以实现清晰性
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions
// Add slug to MarkdownRemark node
if (node.internal.type === 'MarkdownRemark') {
const slug = createFilePath({ node, getNode, basePath: 'library' })
const hero = (fs.existsSync(path.resolve(__dirname, `src/library/pages/${slug}hero.jpg`))) ? './hero.jpg' : ''
createNodeField({
node,
name: 'slug',
value: slug,
})
createNodeField({
node,
name: 'hero',
value: hero,
})
}
}
答案 0 :(得分:1)
我意识到我以前的答案是错误的,并且过于复杂(它依赖于节点创建顺序,也不需要向imageSharp节点添加字段。如果有人感兴趣,这里是the link。)这是更好的答案:
hero
名称的图像由于英雄图像始终与降价文件位于同一目录中,因此我们只需根据其目录进行查询即可。
dir name ext
┌────────────┴────────────┐ ┌─┴─┐ ┌─┴─┐
absolute/path/to/directory/ hero .png
absolute/path/to/directory/ index .md
Graphql查询:
file ( dir: { eq: "absolute/path/to/directory" }, name: { "hero" } ) {
childImageSharp {
fixed {
src
}
}
}
您只需对gatsby-node.js
进行修改,就是将此dir
字段添加到页面的context
中,以便我们将其用作变量。
我们可以通过执行dir
来获得此path.parse(node.fileAbsolutePath).dir
,或者从备注的父节点dir
getNode(node.parent.id).dir
字段。
+ const { dir } = getNode(node.parent.id)
createPage({
path: node.fields.slug,
component,
context: {
+ dir,
slug: node.fields.slug,
},
})
并像这样查询它:
export const pageQuery = graphql`
- query ArticleByPath($slug: String!) {
+ query ArticleByPath($slug: String!, $dir: String!) {
markdownRemark(fields: { slug: { eq: $slug } }) {
id
htmlAst
frontmatter {
title
}
}
+ file (dir: { eq: $dir }, name: { eq: "hero" }) {
+ childImageSharp {
+ fixed {
+ src
+ }
+ }
+ }
}
`
并使用它:
export default function Template({ data }) {
const post = data.markdownRemark
+ const hero = data.file ? data.file.childImageSharp : null
return (
<div className="landing-page-container">
<Helmet title={`Your Blog Name - ${post.frontmatter.title}`} />
<div className="blog-post">
+ {hero && <img src={hero.fixed.src} alt={post.frontmatter.title} />}
<h1>{post.frontmatter.title}</h1>
<div className="blog-post-content">{renderAst(post.htmlAst)}</div>
</div>
</div>
)
}