我想从frontmatter读取markdown内容。 例如:
halfBlocks: -标题:这是第一个标题 内容:>- ###这是** MarkDown **格式的实际内容。 -这是第一行 -这是第二排 -这是第三排 -标题:这是第二个标题 内容:>- ###这是** MarkDown **格式的实际内容。 -这是第一行 -这是第二排 -这是第三排
我正在使用以下graphql:
halfBlocks { 标题 图片 内容 }
如何阅读转换为HTML或显示为HTML的内容?
我希望能够从markdown文件中读取“ index.md”并将其呈现为HTML。
Markdown按原样显示,没有任何解释。
npm list gatsby
):gatsby@^1.9.247gatsby --version
):1.1.50本教程将详细介绍这一过程,特别是第5-7部分https://www.gatsbyjs.org/tutorial/
您可能还想从一个启动程序开始-其中许多已经设置了降价支持-https: //www.gatsbyjs.org/docs/gatsby-starters/
这个问题更加细微,本教程未涵盖,因此我将重新打开它。
我认为您有2种选择:
Separate file - let's call it `someContent.md`
```md
### This is the actual content in **MarkDown** format.
- This is the first row
- This is second row
- This is third row
```
and reference that file in your main file (by relative path):
```md
halfBlocks:
- title: This is first title
content: "./someContent.md"
```
then in query you could
```
halfBlocks {
content {
childMarkdownRemark {
html
}
}
```
createNodeField
添加它们。 这涉及更多。 您可能需要浏览Contentful源插件,以了解如何创建MarkdownRemark节点。嗨@KyleAMathews谢谢您的建议。 我确实读过它们,但是对我来说很难完全理解如何去做。 我正在使用启动器,但这涉及更多。 使用的入门工具: https :
@pieh非常感谢您的指导。 你是对的。 我认为我将有太多的小文件,所以我使用下面的代码来完成此工作。 我在这里对此进行记录,以便如果其他人有相同的问题,他们也可以看到。
我通常通过Graphql阅读内容。 这给了我降价作为一个字符串。 我仍然需要转换。
为此,我决定让内容作为字符串,直到到达将要显示此内容的实际组件为止。 在那里,我将其转换为降价。
添加备注以编程方式执行此操作。 您也许可以忽略remark-preset-lint-recommended:
安装备注
yarn add remark remark-preset-lint-recommended remark-html
进口
import remark from 'remark';
import recommended from 'remark-preset-lint-recommended';
import remarkHtml from 'remark-html';
渲染
稍后在渲染部分中假设content
是作为字符串读取的减价:
content = remark()
.use(recommended)
.use(remarkHtml)
.processSync(content).toString();
现在,我可以将内容重新解释为HTML。
我遇到了另外一个陷阱。 当我在>-
使用多行时,格式不正确:
content: >-
### This is the actual content in **MarkDown** format.
- This is the first row
- This is second row
但是使用管道符号|
可以很好地工作。
content: |
### This is the actual content in **MarkDown** format.
- This is the first row
- This is second row
现在,我要关闭这个。 如果您愿意,请随时重新打开。
谢谢!!
我也想将markdown用作前题(确切地说是标题和摘录),我认为默认情况下应该支持它。
拥有一个命名约定会很棒,这样gatsby-transformer-remark
可以理解例如title.md
是一个markdown字段。
@omeid @ thorn0这可能是我们在gatsby-transformer-remark中直接支持的内容,但与此同时,您可以创建一个为您执行此操作的插件,例如https://github.com/gatsbyjs/gatsby/issues/5729#issuecomment -395701042和createNodeField
很抱歉在已经结束的问题上发表评论,但是只想分享我在自己引用的gatsby-node.js
中使用的摘要,请参考大家引用的内容:
// Need to `yarn add remark remark-html`, then include the following code in
// gatsby-node.js.
const remark = require('remark');
const remarkHTML = require('remark-html');
exports.onCreateNode = ({ node }) => {
// Conditionals, etc. can be used here, but I omitted those just for example's sake.
const markdown = node.frontmatter.my_field;
node.frontmatter.my_field = remark()
.use(remarkHTML)
.processSync(markdown)
.toString();
return node;
};
因此,不使用createNodeField
可以这样做吗? 我很困惑。
@ thorn0最好使用createNodeField
代替node.frontmatter.my_field =
因为突变node
可能导致难以调试的错误
@amitjindal @nshki运行良好,但是由于我安装了“ react-flickity-component”库,因此完全使我的生产构建过程崩溃:
success delete html and css files from previous builds — 0.626 s
success open and validate gatsby-config — 0.018 s
success copy gatsby files — 0.075 s
success onPreBootstrap — 2.782 s
error UNHANDLED EXCEPTION
TypeError: Cannot set property 'Compiler' of null
- index.js:16 plugin
[blog]/[remark-html]/index.js:16:17
- index.js:271 Function.use
[blog]/[unified]/index.js:271:25
- gatsby-node.js:63 exports.onCreateNode.postscriptumsMarkdown.forEach.postscr iptum
/home/projects/blog/gatsby-node.js:63:12
- Array.forEach
- gatsby-node.js:61 Object.exports.onCreateNode
/home/projects/blog/gatsby-node.js:61:29
- api-runner-node.js:110 runAPI
[blog]/[gatsby]/dist/utils/api-runner-node.js:110:36
- api-runner-node.js:187
[blog]/[gatsby]/dist/utils/api-runner-node.js:187:33
- map.js:27
[blog]/[async]/internal/map.js:27:9
- eachOfLimit.js:66 replenish
[blog]/[async]/internal/eachOfLimit.js:66:17
- eachOfLimit.js:50 iterateeCallback
[blog]/[async]/internal/eachOfLimit.js:50:17
- onlyOnce.js:12 module.exports
[blog]/[async]/internal/onlyOnce.js:12:16
- map.js:29
[blog]/[async]/internal/map.js:29:13
- util.js:16 tryCatcher
[blog]/[bluebird]/js/release/util.js:16:23
- nodeify.js:23 Promise.successAdapter
[blog]/[bluebird]/js/release/nodeify.js:23:30
- promise.js:566 Promise.module.exports.Promise._settlePromise
[blog]/[bluebird]/js/release/promise.js:566:21
- promise.js:606 Promise.module.exports.Promise._settlePromiseCtx
[blog]/[bluebird]/js/release/promise.js:606:10
Waiting for the debugger to disconnect...
Process finished with exit code 130 (interrupted by signal 2: SIGINT)
试图从Webpack中排除库不起作用( @see https://github.com/gatsbyjs/gatsby/issues/7599)
嗨,大卫(@comxd),对不起,我在旅行。
不幸的是我对此没有见识。 我试图检查代码。 null上的编译器似乎来自注释库。
您似乎在gatsby-node.js文件中使用了循环。
它可能与某些不是降价或更糟的空内容有关,您正在尝试对其进行处理。 尝试在其中添加一些console.log语句,看看是否找到一种模式,其中某种原因导致了此问题。
这可能是完全不可行的,但您不能只创建如下所示的markdown组件,然后在需要将markdown转换为HTML的任何地方都可以在模板中使用它
import React from 'react'
import PropTypes from 'prop-types'
import showdown from 'showdown'
const converter = new showdown.Converter()
const MarkdownContent = ({ content, className }) => (
<div className={className} dangerouslySetInnerHTML={{ __html: converter.makeHtml(content) }} />
)
MarkdownContent.propTypes = {
content: PropTypes.string,
className: PropTypes.string,
}
export default MarkdownContent
@blakenoll绝对不会完全关闭! 这是一个合理的方法。
就是说,Gatsby的一大好处是您可以在构建时进行这些操作,这很不错,因为这样我们就不必向最终用户购买Markdown解析器了!
@DSchau当应用重新
@blakenoll喜欢开箱即用的想法!
我们是否有任何可用的东西来插入我们包含在gatsby-config.js
中的所有备注插件/配置,所以我们不需要复制幕后完成的所有功能Gatsby的备注实现为我们提供了? 这将使生成节点字段变得容易一些。 但是当您想到嵌套的,可重复的字段以及每页内容的变化时,就显得非常麻烦。
@blakenoll非常感谢您的摊牌提示。 超级有帮助,做了我需要在前端使用HTML的内容。 也就是说,使用Markdown创建网页的方法似乎很笨拙,该网页需要将不同的内容传递到页面的不同部分。
有什么方法可以在graphQL查询的frontmatter部分中应用某种markdownParser函数(类似于我们可以操作图像的方式),该函数将在frontmatter中解析传入的markdown字符串并将其转换为HTML? 不是graphQL专家...只是想想而已。
如果一个人将Gatsby与Netifly CMS一起使用,这是IMO b / c的一个重要问题,Netifly提供了使各种前题字段接受Markdown作为值的选项。 但是,当查询这些字段时,它们将作为markdown以字符串形式返回,而不是解析为HTML。 @amitjindal和@blakenoll的解决方案有效,但是正如@DSchau所提到的,如果我们可以避免将markdown解析传递给用户,则不是最好的选择。 有谁比我更熟悉Gatbsy?
@skylarweaver我绝对和你在同一页面上。 虽然我确实了解创建可以解析此信息的节点字段的本质,但对于CMS数据来说可能有点笨拙,而CMS数据可能具有可重复的字段以及大量的字段名称变体以供筛选。 当时还没有明确的方法来重新使用任何/所有Gatsby Remark插件。
+1 @skylarweaver说的!
@amitjindal也许是愚蠢的问题,但是“>-”还能做什么? 使用netlify cms启动程序,无论我有>,>-,|还是什么都没有,似乎对生成的输出没有任何影响。
@ nol13参见块标量,关于换行符。
如何插入表格? 这行不通
content: |
| | | | | |
|---|---|---|---|---|
| | | | | |
| | | | | |
| | | | | |
@ qnguyen12我会尝试使用https://jmalarcon.github.io/markdowntables/之类的工具来帮助您进行转换。
是的,我是说它是作为源而不是表呈现的
例如:
text: |
test
### This is the actual content in **MarkDown** format.
|Month|Savings|Spending|
|--- |--- |--- |
|January|$100|$900|
|July|$750|$1000|
|December|$250|$300|
|April|$400|$700|
它产生:
测试
|每月|节省|支出| | --- | --- | --- | |一月| $ 100 | $ 900 | | 7月| $ 750 | $ 1000 | | 12月| $ 250 | $ 300 | |四月| $ 400 | $ 700 |
@KyleAMathews谢谢您的工作,但是显然您需要回复备注插件配置和插件,否则您将获得不同的结果。 有什么计划支持降价活动吗? 也许frontmattermd
字段与原始frontmatter
?
@omeid我没有任何计划,这对某人来说是一个很棒的插件,可以与社区创建和共享!
我创建了一个应该执行此操作的插件: gatsby-transformer-remark-frontmatter 。 从我的测试看来,它似乎是行得通的,并且我正计划在为客户做的项目中使用它,但是如果您能看一下并告诉我是否有任何看起来不正确的东西,我将不胜感激,因为这是我第一次编写gatsby插件。 它采用@omeid建议的路线,并将frontmattermd
字段添加到MarkdownRemark节点。
最初,在我意识到可以创建新的markdown文件节点供gatsby-transformer-remark使用之前,我想出了一个非常棘手的解决方案,涉及调用由gatsby-transformer-remark的setFieldsOnGraphQLNodeType函数导出的解析器,并传入一个新的在另一个解析器中创建的markdown节点。 这允许使用字段枚举查询MarkdownRemark节点上的任何字段,该枚举用于组函数,这是我真正喜欢的,但实际上很多东西都想借用。 我将其保存在这里供后代使用。
嗨@WhiteAbeLincoln,我尝试安装并测试:
npm i gatsby-transformer-remark-frontmatter
npm ERR! code ENOVERSIONS
npm ERR! No valid versions available for gatsby-transformer-remark-frontmatter
抱歉,我意识到还没有发布到npm。 下班后我会发布它,并通知您。
—安倍·怀特
2019年6月17日,22:53,broeker [email protected]写道:
嗨@WhiteAbeLincoln,我尝试安装并测试:
npm我gatsby-transformer-remark-frontmatter npm错误! 代码ENOVERSIONS npm ERR! 没有适用于gatsby-transformer-remark-frontmatter的有效版本-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看,或使该线程静音。
@WhiteAbeLincoln我尝试了gatsby-transformer-remark-frontmatter,但它给了我一个错误。
错误#11325
您网站的“ gatsby-node.js”创建了一个页面,该页面包含不存在的组件。
你得到这个错误吗?
它最初是由@obeid在您的存储库的问题日志中报告的。
也许我只是没有正确使用它。 因此,一些帮助表示赞赏。
建立在@nshki答案之上,并带有@pieh来评论节点突变。 这完全对我有用:
const remark = require("remark");
const remarkHTML = require("remark-html");
exports.onCreateNode = ({ node, actions: { createNodeField } }) => {
const my_field = node.frontmatter.my_field;
if (my_field) {
const value = remark()
.use(remarkHTML)
.processSync(my_field)
.toString();
// new node at:
// fields {
// my_field_html
// }
createNodeField({
name: `my_field_html`,
node,
value
});
}
};
编辑: my_field
=> my_field_html
@aziaziazi除了嵌套在数组中的字段外,我该如何做同样的事情?
---
pressEventsList:
- body: >-
*My md content...*
image: 'https://res.cloudinary.com/press/01.jpg'
- body: >-
*My md content...*
image: 'https://res.cloudinary.com/press/02.jpg'
---
我需要转换每个pressEventsList[i].body
。
@alexeychikk我想您可能会寻找pressEventList
,然后映射内容以创建结果数组:
const remark = require("remark");
const remarkHTML = require("remark-html");
exports.onCreateNode = ({ node, actions: { createNodeField } }) => {
const pressEventList = node.frontmatter.pressEventList;
if (pressEventList) {
const value = pressEventList.map(event =>
remark()
.use(remarkHTML)
.processSync(event.body)
.toString()
)
createNodeField({
name: `pressEventList`,
node,
value
});
}
};
我有兴趣创建一个插件来解析自定义YAML标签以实现上述功能,而无需使用createNodeField
(与清晰解析图像URL相同的方式)。
谁能指出我解析图像URL的代码,以查看当前如何使用sharp进行处理的示例?
👋对于使用MDX的用户,我创建了一个插件来添加frontmatter支持https://www.gatsbyjs.org/packages/gatsby-plugin-mdx-frontmatter/
@zslabs ,您通常不会看到“ 9小时前”发布的解决方案! 我会旋转一下! 辛苦了
我一直在为此苦苦挣扎,因为我想为自己的页面之一使用更复杂的数据结构。
在前题中,我有一系列部分,其中有一些字段,例如标题和特色图片,然后在每个字段上,我都用markdown制作了一个主体。
使用createNodeField并不是对我有用,因为我无法逻辑地链接它们,因为它们是在自己的字段中创建的,而不是附加到现有的frontmatter结构中。
我最终使用了createFieldExtension,以便查询我的section.body时,它以HTML返回。
如果这不是一个好的解决方案,请有人纠正我,这似乎对我有用,但我有na的感觉,这是错误的解决方法。
我的前题结构看起来像这样:
templateKey: project-entry
date: 2020-06-22T13:16:57.702Z
featuredproject: true
title: Project title
description: Description for listing the project on other pages
featuredimage: Image for listing the project on other pages
featuredpost: false
sections:
- heading: Section heading
standout: false
intro: >-
Introduction to be displayed separately to body
body: >-
## section title
* bullet point
* bullet point
Some other text here
还有我在gatsby-node.js中使用的代码
exports.createSchemaCustomization = ({actions}) => {
const { createTypes, createFieldExtension} = actions
createFieldExtension({
name: 'toHTML',
extend:() => ({
resolve(source) {
return remark().use(remarkHTML).processSync(source.body).toString()
}
})
})
const typeDefs = `
type MarkdownRemark implements Node {
frontmatter: Frontmatter
}
type Frontmatter <strong i="14">@infer</strong> {
sections: [section]
}
type section <strong i="15">@infer</strong> {
body: String <strong i="16">@toHTML</strong>
}
`
createTypes(typeDefs)
}
对于其他感兴趣的人,我使用自定义的YAML类型解决了该问题,以允许将任意字段解析为markdown,如下所示:
---
title: My Page
inline: !md Some **bold** and _italic_ text
block: !md |
## I'm a H2 title
[I'm an inline-style link](https://www.google.com)
---
为此,创建一个自定义类型,然后重写grey-matter的YAML解析器:
// custom-yaml.js
const yaml = require('js-yaml')
const remark = require('remark')
const remarkHTML = require('remark-html')
const MarkdownYamlType = new yaml.Type('!md', {
kind: 'scalar',
construct: data => remark().use(remarkHTML).processSync(data).toString(),
})
const MARKDOWN_SCHEMA = yaml.Schema.create(MarkdownYamlType)
module.exports = doc => yaml.safeLoad(doc, { schema: MARKDOWN_SCHEMA })
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
engines: { yaml: require("path/to/custom-yaml.js") },
},
}
]
}
我解决了这个问题。 我创建了一个名为@md的字段扩展,并将其用于frontmatter类型定义中,并与字段重命名结合使用,从而可以实现所需的抽象。
exports.createSchemaCustomization = ({ actions }) => {
actions.createFieldExtension({
name: "md",
args: {
from: {
type: "String!",
defaultValue: true,
},
},
extend() {
return {
args: {
from: "String!",
},
resolve(source, args) {
const fieldValue = source[args.from]
return convertToHTML(fieldValue)
},
}
},
})
const typeDefs = `
type MarkdownRemark implements Node <strong i="7">@infer</strong> {
frontmatter: Frontmatter
}
type Frontmatter {
markdownField: String! <strong i="8">@md</strong>
}
`
actions.createTypes(typeDefs)
}
这是一个示例用法:
...
frontmatter {
title: markdownField(from: "title")
subtitle: markdownField(from: "subtitle")
}
我解决了这个问题。
这对我来说不太有效。 首先,我收到一个错误,拒绝参数from
的defaultValue: true
from
-它必须是一个字符串。 将其更改为defaultValue: ''
,然后出现此错误:
Encountered an error parsing the provided GraphQL type definitions:
Argument "from" of required type "String!" was not provided.
1 |
2 | type MarkdownRemark implements Node <strong i="11">@infer</strong> {
3 | frontmatter: Frontmatter
4 | }
5 | type Frontmatter {
> 6 | markdownField: String! <strong i="12">@md</strong>
| ^
7 | }
我不知道该怎么解决。
对于其他感兴趣的人,我使用自定义的YAML类型解决了该问题,以允许将任意字段解析为markdown,如下所示:
--- title: My Page inline: !md Some **bold** and _italic_ text block: !md | ## I'm a H2 title [I'm an inline-style link](https://www.google.com) ---
为此,创建一个自定义类型,然后重写grey-matter的YAML解析器:
// custom-yaml.js const yaml = require('js-yaml') const remark = require('remark') const remarkHTML = require('remark-html') const MarkdownYamlType = new yaml.Type('!md', { kind: 'scalar', construct: data => remark().use(remarkHTML).processSync(data).toString(), }) const MARKDOWN_SCHEMA = yaml.Schema.create(MarkdownYamlType) module.exports = doc => yaml.safeLoad(doc, { schema: MARKDOWN_SCHEMA })
// gatsby-config.js module.exports = { plugins: [ { resolve: `gatsby-transformer-remark`, options: { engines: { yaml: require("path/to/custom-yaml.js") }, }, } ] }
我尝试使用“ gatsby-transformer-remark”无效的插件选项吗?
最有用的评论
这可能是完全不可行的,但您不能只创建如下所示的markdown组件,然后在需要将markdown转换为HTML的任何地方都可以在模板中使用它