frontmatter์์ ๋งํฌ ๋ค์ด ์ฝํ ์ธ ๋ฅผ ์ฝ๊ณ ์ถ์ต๋๋ค. ์๋ฅผ ๋ค๋ฉด :
halfBlocks : -์ ๋ชฉ : ์ฒซ ๋ฒ์งธ ์ ๋ชฉ์ ๋๋ค. ๋ด์ฉ :>- ### ** MarkDown ** ํ์์ ์ค์ ์ฝํ ์ธ ์ ๋๋ค. -์ด๊ฒ์ ์ฒซ ๋ฒ์งธ ํ์ ๋๋ค -๋ ๋ฒ์งธ ์ค์ ๋๋ค -์ด๊ฒ์ ์ธ ๋ฒ์งธ ์ค์ ๋๋ค -์ ๋ชฉ : ๋ ๋ฒ์งธ ์ ๋ชฉ์ ๋๋ค. ๋ด์ฉ :>- ### ** MarkDown ** ํ์์ ์ค์ ์ฝํ ์ธ ์ ๋๋ค. -์ด๊ฒ์ ์ฒซ ๋ฒ์งธ ํ์ ๋๋ค -๋ ๋ฒ์งธ ์ค์ ๋๋ค -์ด๊ฒ์ ์ธ ๋ฒ์งธ ์ค์ ๋๋ค
๋ค์ graphql์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
halfBlocks { ํ์ ์์ ํจ์ ๋ }
HTML๋ก ๋ณํ ๋ ์ปจํ ์ธ ๋ฅผ ์ฝ๊ฑฐ๋ HTML๋ก ํ์ํ๋ ค๋ฉด ์ด๋ป๊ฒํฉ๋๊น?
๋๋ ์ด๊ฒ์ '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/
์ง๋ฌธ์ ๋ ๋ฏธ๋ฌํ๊ณ ํํ ๋ฆฌ์ผ์์ ๋ค๋ฃจ์ง ์์ผ๋ฏ๋ก ๋ค์ ์ด์ด ๋ณด๊ฒ ์ต๋๋ค.
์ ์๊ฐ์๋ ๋ ๊ฐ์ง ์ต์ ์ด ์์ต๋๋ค.
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
๋ฅผ ํตํด ์ถ๊ฐํ๋ ๊ฒ์
๋๋ค. ์ด๊ฒ์ ๋ ๋ณต์กํฉ๋๋ค. MarkdownRemark ๋
ธ๋๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ณด๋ ค๋ฉด Contentful ์์ค ํ๋ฌ๊ทธ์ธ์ ์ฐพ์์ผ ํ ๊ฒ์
๋๋ค.์๋ ํ์ธ์ @KyleAMathews ๊ทํ์ ์ ์์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๋๋ ๊ทธ๊ฒ๋ค์ ์ฝ์์ง๋ง ์ด๊ฒ์ ๋ํด ์์ ํ ์ดํดํ๊ธฐ๊ฐ ์ด๋ ค์ ๋ค. ๋๋ ์คํํฐ๋ฅผ ์ฌ์ฉํ๊ณ ์์ง๋ง ์ด๊ฒ์ ๋ ๋ณต์กํ์ต๋๋ค. ์ฌ์ฉ ๋ ์คํํฐ : https://github.com/v4iv/gatsby-starter-business
@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
์ง๊ธ์ ์ด๊ฒ์ ๋ซ์ต๋๋ค. ์ํ์๋ฉด ์ธ์ ๋ ์ง ์ฌ๊ฐ ์ฅํ์ญ์์ค.
๊ฐ์ฌ!!
๋๋ ํ์ (์ ๋ชฉ, ์ ํํ ๋ฐ์ท)์๋ ๋งํฌ ๋ค์ด์ ์ฌ์ฉํ๊ณ ์ถ์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์๋์ด์ผํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
gatsby-transformer-remark
๊ฐ ์๋ฅผ ๋ค์ด title.md
๊ฐ ๋งํฌ ๋ค์ด ํ๋๋ผ๋ ๊ฒ์ ์ดํดํ ์ ์๋๋ก ๋ช
๋ช
๊ท์น์ ๊ฐ๋ ๊ฒ์ด ์ข์ต๋๋ค.
@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 ์ node.frontmatter.my_field =
createNodeField
๋์ 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).
์๋
ํ์ธ์ David (@comxd), ์ฌํ ์ค์ด ์ด์ ์ฃ์กํฉ๋๋ค.
๋ถํํ๋ ๋๋ ์ด๊ฒ์ ๋ํ ํต์ฐฐ๋ ฅ์ด ์์ต๋๋ค. ์ฝ๋๋ฅผ ํ์ธํ๋ ค๊ณ ํ์ต๋๋ค. null์ ์ปดํ์ผ๋ฌ๋ ๋น๊ณ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ค๋ ๊ฒ ๊ฐ์ต๋๋ค.
gatsby-node.js ํ์ผ์์ ๋ฃจํ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋งํฌ ๋ค์ด์ด ์๋๊ฑฐ๋ ๋น์ด์๋ ์ผ๋ถ ์ฝํ
์ธ ์ ๊ด๋ จ์ด์์ ์ ์์ผ๋ฉฐ ์ฒ๋ฆฌํ๋ ค๊ณ ํฉ๋๋ค. ๊ฑฐ๊ธฐ์ console.log ๋ฌธ์ ๋ฃ๊ณ ๋น์ด์๋ ๊ฒ์ด ์์ธ์ด๋๋ ํจํด์ ์ฐพ๋ ์ง ํ์ธํ์ญ์์ค.
์ด๊ฒ์ ์์ ํ ๊บผ์ ธ์์ ์ ์์ง๋ง 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 ์ฑ์ด ์ฌ์ ํ ๋ ๋ Markdown ํ์๊ฐ ์ค์ ๋ก ์ฌ์ฉ์์๊ฒ ๋ฐฐ์ก๋์ง ์์ต๋๊น?
@blakenoll ์ฆ์ ์ฌ์ฉ ๊ฐ๋ฅํ ์๊ฐ์ ์ฌ๋ํ์ญ์์ค!
gatsby-config.js
๋ด์ ํฌํจ ๋ ๋ชจ๋ remark ํ๋ฌ๊ทธ์ธ / ๊ตฌ์ฑ์ ๊ฐ์ ธ์ฌ ์์๋ ๊ฒ์ด ์์ต๋๊น? ๊ทธ๋์ Gatsby์ remark ๊ตฌํ์ด ์ ๊ณตํ๋ ๋ชจ๋ ๊ธฐ๋ฅ์ ๋ณต์ ํ ํ์๊ฐ ์์ต๋๋ค. ? ๊ทธ๋ฌ๋ฉด ๋
ธ๋ ํ๋๋ฅผ ์ข ๋ ์ฝ๊ฒ ์์ฑ ํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ค์ฒฉ๋๊ณ ๋ฐ๋ณต ๊ฐ๋ฅํ ํ๋์ ํ์ด์ง ๋น ์ฝํ
์ธ ์ ๋ณํ์ ๋ํด ์๊ฐํ ๋ ์์ฒญ๋๊ฒ ๋ฒ๊ฑฐ ๋กญ์ต๋๋ค.
@blakenoll ๋๊ฒฐ ํ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๋งค์ฐ ๋์์ด๋์๊ณ ํ๋ก ํธ ๋งคํฐ์์ HTML์ ์ฌ์ฉํ๋ ๋ฐ ํ์ํ ์์ ์ ์ํํ์ต๋๋ค. ์ฆ, Markdown์ ์ฌ์ฉํ์ฌ ํ์ด์ง์ ๋ค๋ฅธ ๋ถ๋ถ์ ๋ค๋ฅธ ์ฝํ ์ธ ์กฐ๊ฐ์ ์ ๋ฌํด์ผํ๋ ์น ํ์ด์ง๋ฅผ ๋ง๋๋ ๋ฐ ์ด์ํ ์ ๊ทผ ๋ฐฉ์์ผ๋ก ๋ณด์ ๋๋ค.
graphQL ์ฟผ๋ฆฌ์ frontmatter ์น์ ๋ด์ ์ผ์ข ์ markdownParser ํจ์๋ฅผ ์ ์ฉ ํ ์์๋ ๋ฐฉ๋ฒ์ด ์์ต๋๊น? (์ด๋ฏธ์ง๋ฅผ ์กฐ์ ํ ์์๋ ๋ฐฉ๋ฒ๊ณผ ์ ์ฌ) frontmatter์์ ๋ค์ด์ค๋ markdown ๋ฌธ์์ด์ ๊ตฌ๋ฌธ ๋ถ์ํ๊ณ ์ด๋ฅผ HTML๋ก ๋ณํ ํ ์ ์์ต๋๊น? graphQL ์ ๋ฌธ๊ฐ๊ฐ ์๋๋๋ค ... ๊ทธ๋ฅ ์๊ฐํ๋ ค๊ณ ํฉ๋๋ค.
Netifly CMS์ ํจ๊ป Gatsby๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ IMO b / c๋ ์ค์ํ ๋ฌธ์ ์ ๋๋ค. Netifly๋ ๋ค์ํ frontmatter ํ๋๊ฐ Markdown์ ๊ฐ์ผ๋ก ๋ฐ์๋ค์ด๋๋กํ๋ ์ต์ ์ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ฌํ ํ๋๋ฅผ ์ฟผ๋ฆฌ ํ ๋ HTML๋ก ๊ตฌ๋ฌธ ๋ถ์๋๋ ๋์ ๋ฌธ์์ด์ ๋งํฌ ๋ค์ด์ผ๋ก ๋ฐํ๋ฉ๋๋ค. @amitjindal ๋ฐ @blakenoll ์ ์๋ฃจ์ ์ ์๋ํ์ง๋ง @DSchau๊ฐ ์ธ๊ธํ๋ฏ์ด ์ฌ์ฉ์์๊ฒ ๋งํฌ ๋ค์ด ๊ตฌ๋ฌธ ๋ถ์์ ํผํ ์์๋ ๊ฒฝ์ฐ ์ ๋ฌํ๋ ๊ฒ์ ๋ฐ๋์งํ์ง ์์ต๋๋ค. ๋๋ณด๋ค Gatbsy๋ฅผ ๋ ์ ์๋ ์ฌ๋์ ์๊ฐ์?
@skylarweaver ๋๋ ํ์คํ ๋น์ ๊ณผ ๊ฐ์ ํ์ด์ง์ ์์ต๋๋ค. ์ด ์ ๋ณด๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ ํ ์์๋ ๋ ธ๋ ํ๋๋ฅผ ๋ง๋๋ ํน์ฑ์ ์ดํดํ๊ณ ์์ง๋ง ๋ฐ๋ณต ๊ฐ๋ฅํ ํ๋์ ์์ฒญ๋๊ฒ ๋ง์ ํ๋ ์ด๋ฆ ๋ณํ์ด์์ ์์๋ CMS ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค์ ๋ค๋ฃจ๊ธฐ ์ด๋ ค์์ง๋๋ค. ๊ทธ ๋น์ ๋ชจ๋ Gatsby Remark ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฌ์ฉํ๋ ๋ช ํํ ๋ฐฉ๋ฒ์ด ์๋ค๋ ๊ฒ์ ๋๋ค.
@skylarweaver๊ฐ ๋งํ ๋ด์ฉ +1!
@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|
๋ค์์ ์์ฑํฉ๋๋ค.
ํ
์คํธ
| ์ | ์ ์ถ | ์ง์ถ | | --- | --- | --- | | 1 ์ | $ 100 | $ 900 | | 7 ์ | $ 750 | $ 1000 | | 12 ์ | $ 250 | $ 300 | | 4 ์ | $ 400 | $ 700 |
@KyleAMathews ๊ฐ์ฌํฉ๋๋ค. ๊ทธ๋ฐ ์ข
๋ฅ์ ์์
์ด์ง๋ง ๋ถ๋ช
ํ ์ค๋ช
ํ๋ฌ๊ทธ์ธ ๊ตฌ์ฑ ๋ฐ ํ๋ฌ๊ทธ์ธ์ ์๋ตํด์ผํ๊ฑฐ๋ ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์ป์ต๋๋ค. ๋งํฌ ๋ค์ด ํ๋ก ํธ ๋งคํฐ๋ฅผ ์ง์ํ ๊ณํ์ด ์์ต๋๊น? frontmattermd
ํ๋์ ์์ frontmatter
?
@omeid ์ ๋ ๊ณํ์ด ์์ต๋๋ค. ์ด๊ฒ์ ๋๊ตฐ๊ฐ๊ฐ ๋ง๋ค๊ณ ์ปค๋ฎค๋ํฐ์ ๊ณต์ ํ ์์๋ ํ๋ฅญํ ํ๋ฌ๊ทธ์ธ์ด ๋ ๊ฒ์ ๋๋ค!
์ด ์์
์ ์ํํด์ผํ๋ ํ๋ฌ๊ทธ์ธ์ ๋ง๋ค์์ต๋๋ค : gatsby-transformer-remark-frontmatter . ๋ด ํ
์คํธ์์ ์๋ํ๋ ๊ฒ ๊ฐ๊ณ ํด๋ผ์ด์ธํธ๋ฅผ ์ํด ์ํํ๋ ํ๋ก์ ํธ์์ ์ฌ์ฉํ ๊ณํ์ด์ง๋ง ์ฌ๋ฌ๋ถ์ด ์ดํด๋ณด๊ณ ์๋ชป๋ ๊ฒ์ด ์์ผ๋ฉด ์๋ ค ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค. , ์ฒ์์ผ๋ก gatsby ํ๋ฌ๊ทธ์ธ์ ์์ฑํ์ต๋๋ค. @omeid๊ฐ ์ ์ํ ๊ฒฝ๋ก๋ฅผ ์ทจํ๊ณ MarkdownRemark ๋
ธ๋์ frontmattermd
ํ๋๋ฅผ ์ถ๊ฐํฉ๋๋ค.
์ฒ์์๋ gatsby-transformer-remark๊ฐ ์ฌ์ฉํ ์ ๋งํฌ ๋ค์ด ํ์ผ ๋ ธ๋๋ฅผ ์์ฑ ํ ์ ์๋ค๋ ์ฌ์ค์ ๊นจ๋ซ๊ธฐ ์ ์ gatsby-transformer-remark์ setFieldsOnGraphQLNodeType ํจ์์์ ๋ด ๋ณด๋ธ ๋ฆฌ์กธ๋ฒ๋ฅผ ํธ์ถํ๊ณ ์๋ก์ด ๋ค๋ฅธ ๋ฆฌ์กธ๋ฒ ๋ด์์ ์์ฑ ๋ ๋งํฌ ๋ค์ด ๋ ธ๋. ์ด๋ ๊ฒํ๋ฉด ํ๋ ์ด๊ฑฐ ํ์ ์ฌ์ฉํ์ฌ 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 i gatsby-transformer-remark-frontmatter npm ERR! ์ฝ๋ ENOVERSIONS npm ERR! gatsby-transformer-remark-frontmatter์ ์ ํจํ ๋ฒ์ ์ด ์์ต๋๋ค.โ
๋น์ ์ด ์ธ๊ธ ๋์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๋ฐ๊ณ ์์ต๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ฑฐ๋ GitHub์์ ๋ณด๊ฑฐ๋ ๋ํ ๋ชฉ๋ก์ ์์๊ฑฐํ์ธ์.
@WhiteAbeLincoln ๋๋ gatsby-transformer-remark-frontmatter๋ฅผ ์๋ ํ์ง๋ง ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
์ค๋ฅ # 11325
์ฌ์ดํธ์ "gatsby-node.js"๊ฐ ์กด์ฌํ์ง ์๋ ๊ตฌ์ฑ ์์๊ฐ์๋ ํ์ด์ง๋ฅผ ์์ฑํ์ต๋๋ค.
์ด ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๊น?
์๋ ๋ฆฌํฌ์งํ ๋ฆฌ ์ ๋ฌธ์ ๋ก๊ทธ์
์๋ง๋ ๋๋ ๊ทธ๊ฒ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉํ์ง ์์ ๊ฒ์ ๋๋ค. ๊ทธ๋์ ๋์์ ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.
@nshki ๋ต๋ณ ์ ๊ธฐ๋ฐ์ผ๋ก ํ๊ณ ๋ ธ๋ ๋ณํ์ ๋ํ
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
});
}
};
createNodeField
๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์์ ์์
์ ์ํํ๊ธฐ ์ํด ์ฌ์ฉ์ ์ง์ YAML ํ๊ทธ๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ํ๋ ํ๋ฌ๊ทธ์ธ์ ๋ง๋๋ ๋ฐ ๊ด์ฌ์ด ์์ต๋๋ค (์คํ ์ด๋ฏธ์ง URL ๊ตฌ๋ฌธ ๋ถ์๊ณผ ๊ฐ์ ๋ฐฉ์).
๋๊ตฌ๋ ์ง ์ด๋ฏธ์ง URL์ด ํ์ฑ๋๋ ์ฝ๋๋ฅผ ์๋ ค์ค ์ ์์ต๋๊น?
๐ MDX๋ฅผ ์ฌ์ฉํ๋ ์ฌ๋๋ค์ ์ํด frontmatter ์ง์์ ์ถ๊ฐํ๋ ํ๋ฌ๊ทธ์ธ์ ๋ง๋ค์์ต๋๋ค https://www.gatsbyjs.org/packages/gatsby-plugin-mdx-frontmatter/
@zslabs , "9 ์๊ฐ ์ ์"๊ฒ์ ๋ ์๋ฃจ์ ์ ์์ฃผ ๋ณด์ง ์์ต๋๋ค! ๋ด๊ฐ ๋๋ ค ์ค๊ฒ! ์ ํ์ด.
๋ด ํ์ด์ง ์ค ํ๋์ ๋ ๋ณต์กํ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๊ณ ์ถ์ ๊ธฐ ๋๋ฌธ์์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๊ณ ์ฌํ๊ณ ์์ต๋๋ค.
Frontmatter์๋ ์ ๋ชฉ ๋ฐ ์ถ์ฒ ์ด๋ฏธ์ง์ ๊ฐ์ ๋ช ๊ฐ์ ํ๋๊ฐ์๋ ์น์
๋ฐฐ์ด์ด ์์๊ณ ๊ฐ ์น์
์๋ ๋งํฌ ๋ค์ด์ผ๋ก ๋ง๋ ๋ณธ๋ฌธ์ด ์์ต๋๋ค.
createNodeField๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ธฐ์กด์ frontmatter ๊ตฌ์กฐ์ ์ถ๊ฐ๋์ง ์๊ณ ์์ฒด ํ๋์์ ์์ฑ ๋์๊ธฐ ๋๋ฌธ์ ๋
ผ๋ฆฌ์ ์ผ๋ก ์ฐ๊ฒฐํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์์๊ธฐ ๋๋ฌธ์ ์ ์๊ฒ ์ ํฉํ์ง ์์์ต๋๋ค.
๋ด section.body๊ฐ ์ฟผ๋ฆฌ๋๋ฉด HTML๋ก ๋ฐํ๋๋๋ก createFieldExtension์ ์ฌ์ฉํ์ต๋๋ค.
์ด๊ฒ์ด ์ข์ ํด๊ฒฐ์ฑ
์ด ์๋๋ผ๋ฉด ๋๊ตฐ๊ฐ ๋๋ฅผ ๋ฐ๋ก ์ก์ผ์ญ์์ค. ๋์๊ฒ ํจ๊ณผ๊ฐ์๋ ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง ์ด๊ฒ์ด ์๋ชป๋ ๋ฐฉ๋ฒ์ด๋ผ๋ ๋๋์ด ๋ค์์ต๋๋ค.
๋ด frontmatter ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
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 ์ ํ์ ์ฌ์ฉํ์ฌ ์์์ ํ๋๋ฅผ ๋งํฌ ๋ค์ด์ผ๋ก ๊ตฌ๋ฌธ ๋ถ์ ํ ์ ์๋๋ก ํด๊ฒฐํ์ต๋๋ค.
---
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
์ ๊ฑฐ๋ถํ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. ๋ฌธ์์ด์ด์ด์ผํฉ๋๋ค. 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 ์ ํ์ ์ฌ์ฉํ์ฌ ์์์ ํ๋๋ฅผ ๋งํฌ ๋ค์ด์ผ๋ก ๊ตฌ๋ฌธ ๋ถ์ ํ ์ ์๋๋ก ํด๊ฒฐํ์ต๋๋ค.
--- 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"์ ๋ํ ์๋ชป๋ ํ๋ฌ๊ทธ์ธ ์ต์ ์ด ๋ํ๋ฉ๋๋ค.์ด ๋ฐฉ๋ฒ์ ์๋ํ๋ฉด?
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ด๊ฒ์ ์์ ํ ๊บผ์ ธ์์ ์ ์์ง๋ง HTML๋ก ๋ณํํด์ผํ๋ ๋งํฌ ๋ค์ด์ด ํ์ํ ๋ชจ๋ ๊ณณ์์ ํ ํ๋ฆฟ์์ ์ฌ์ฉํ ์์๋ ์๋์ ๊ฐ์ ๋งํฌ ๋ค์ด ๊ตฌ์ฑ ์์๋ฅผ ๋ง๋ค ์๋ ์์ต๋๋ค.