Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs/add markdown page #3111

Merged
merged 6 commits into from
Dec 14, 2017
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 158 additions & 3 deletions docs/docs/adding-markdown-pages.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,162 @@
title: Adding Markdown Pages
---

This is a stub. Help our community expand it.
Gatsby can easily convert Markdown pages to static pages in your site.
It provides plugins to read and understand folders with markdown files and
node api, which help you create static pages automatically.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My initial feedback is to make sure you write API with all caps. And are you referring to Node.js API? Because if so, then Node.js is capitalized too.

Here's how you do it step by step.

1. Read files in Gatsby from the filesystem.
2. Understand Markdown syntax. Convert metadata to api and content to html.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe HTML is also in all caps.

3. Create a page template from above Markdown data and style it.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"from" should be "for" to match heading below?

4. Create static pages using Gatsby's node api at paths you like.

### Read files in Gatsby from the filesystem - `gatsby-source-filesystem`

Use the plugin [`gatsby-source-filesystem`](https://www.gatsbyjs.org/packages/gatsby-source-filesystem/#gatsby-source-filesystem) to read files off of defined file paths.

`npm i --save gatsby-source-filesystem`

Now open up your `gatsby-config.js` to add this plugin to the plugin list.

The plugin list accepts either a string which is the plugin name or an object with any options you may want to pass.
Here we add an object with the path as an option to the plugin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is missing punctuation, like a period or colon at the end.


```
plugins: [
`...`,
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/path/for/markdown/files`,
name: 'markdownpages'
}
}
]
```
The output of this plugin can be consumed by 'transformer' plugins in Gatsby.

### Understand markdown syntax. - `gatsby-transformer-remark`

Use the plugin [`gatsby-transformer-remark`](https://www.gatsbyjs.org/packages/gatsby-transformer-remark/) to recognise files which are markdown and read it's content. It will convert the frontmatter metadata part of your markdown file as `frontmatter` and the content part as html.

`npm i --save gatsby-transformer-remark`

Add this to `gatsby-config.js`. Since there are no options needed,

```
plugins: [`gatsby-transformer-remark`]
```

#### Note on creating markdown files.

When you create a Markdown file, you can add a block that looks like below to the top of the file content. This block will be parsed by `gatsby-transformer-remark` as `frontmatter`. The GraphQL api will provide this data in our React components.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"that looks like the block below"


```
---
path: "/blog/my-first-post"
date: "2017-11-07"
title: My first blog post"
---
```

### Create a page template for the markdown data.

Create a folder in the `/src` directory of your Gatsby application called `templates`.
Now create a `blogTemplate.js` inside it with the following content.

```
import React from "react"

export default function Template({
data, // this prop will be injected by the GraphQL query below.
}) {
const { markdownRemark } = data // data.markdownRemark holds our post data
const {frontMatter, html} = markdownRemark;
return (
<div className="blog-post-container">
<div className="blog-post">
<h1>{frontmatter.title}</h1>
<h2>{frontmatter.date}</h2>
<div
className="blog-post-content"
dangerouslySetInnerHTML={{ __html: html }}
/>
</div>
</div>
)
}

export const pageQuery = graphql`
query BlogPostByPath($path: String!) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you offer just a little more about who / how the $path variable is getting filled in? I thought it would get set in the context parameter in gatsby-node.js but I don't see it there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review!
So that's a graphQL thingy which I don't completely understand honestly :(
Regardless, wouldn't the right thing to do be point to graphQL docs or graphQL-Gatsby docs at this stage? It would be awfully irrelavant explaining graphQL query structure here no?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't mean explain how graphql variables work, I mean specifically what sets the value for that $path variable. If that's a standard thing that's explained somewhere else, then a pointer would be good. I haven't found a place it's explained, though. I only figured out some of how they work by reading code in the examples (gatsbygram in particular).

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I really want to say thank you for writing this, it's already helped me a lot.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry for the delay. I really am only trying this out on the weekend. Thanks for the encouragement. Will finish this up soon.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tamouse - I tried figuring this out. I think I have an idea that possibly some Gatsby Node-api magic is involved, but can't say for sure. Would really love somebody's help on this. Maybe @KyleAMathews can help me with this part of the documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

markdownRemark(frontmatter: { path: { eq: $path } }) {
html
frontmatter {
date(formatString: "MMMM DD, YYYY")
path
title
}
}
}
`
```

Two things are important in the file above.
1. A GraphQL query is made in the second half of the file to get the markdown data. Gatsby has automagically given you all the Markdown metadata and html in this query's result.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe Markdown is always capitalized as well.

Note: To learn more about GraphQL, consider this [excellent resource](https://www.howtographql.com/)
2. The result of the query is injected by Gatsby into the `Template` component as `data`. `marksownRemark` is the property that we find has all the details of the Markdown file. We can use that to construct a template for our blogpost view. Since it's a React component, you could style it with any of the recommended styling systems in Gatsby.

### Create static pages using Gatsby's node api.

Gatsby exposes a powerful Node API, which allows for functionality such as creating dynamic pages. This API is exposed in the `gatsby-node.js` file in the root directory of your project, at the same level as `gatsby-config.js`. Each export found in this file will be parsed by Gatsby, as detailed in its [Node API specification](https://www.gatsbyjs.org/docs/node-apis/). However, we only care about one particular API in this instance, `createPages`.

Gatsby calls the `createPages` api (if present) at build time with injected parameters, `boundActionCreators` and `graphql`. Use the `graphql` to query Markdown file data as below. Next use `createPage` action creator to create a page for each of the Markdown files using the `blogTemplate.js` we created in the previous step.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"to query Markdown file data as shown below"


```
const path = require('path');

exports.createPages = ({ boundActionCreators, graphql }) => {
const { createPage } = boundActionCreators;

const blogPostTemplate = path.resolve(`src/templates/blogTemplate.js`);

return graphql(`{
allMarkdownRemark(
sort: { order: DESC, fields: [frontmatter___date] }
limit: 1000
) {
edges {
node {
excerpt(pruneLength: 250)
html
id
frontmatter {
date
path
title
}
}
}
}
}`)
.then(result => {
if (result.errors) {
return Promise.reject(result.errors);
}

result.data.allMarkdownRemark.edges
.forEach(({ node }) => {
createPage({
path: node.frontmatter.path,
component: blogPostTemplate,
context: {} // additional data can be passed via context
});
});
});
}
```

This should get you started on some basic Markdown power in your Gatsby site. You can further customise the `frontmatter` and the template file to get desired effects!



Please use the [Gatsby Style Guide](/docs/gatsby-style-guide/) to ensure your
pull request gets accepted.