gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.27k stars 10.31k forks source link

gatsby-plugin-mdx: I want to swap an object in the markdown body with jsx #22726

Closed apolopena closed 4 years ago

apolopena commented 4 years ago

I have some ideas on how to do this however before I go down the path of creating a gatsby remark plugin that wraps a custom remark plugin. I wanted to vet my approach against anyone who might have done this already or would know a good way to do this.

I have markdown files that will contain stringified objects in them need to be transformed to jsx (custom react component) I believe before the `source and transform nodes' step of gatsby build/develop.

For example the body of my .md file will look like this:

some text here, blah blah blah, an image la la de dah
{"widget":"smartcaption","caption":"The image is described","credit":"by some person"}
more text is here la la la

I need the body to be transformed at the right time to this

some text here, blah blah blah, an image la la de dah
<SmartCaption credit="by some person>The image is described</SmartCaption>
more text is here la la la

Now after some research and searching existing remark plugins to make sure it has not been done before. I am under the impression that I need to create my own remark plugin called something like remark-object-to-jsx and possibly wrap it like gatsby-remark-sectionize does and make a gatsby remark plugin called something like gatsby-remark-object-to-jsx.

Before I go down this path, does anyone see an easier way? Perhaps I missed something and I am making this more involved than needed or does this seems like a sound approach to acheive what I need done? Thanks for taking a look.

pieh commented 4 years ago

Would you need to import those components as well in .md files or would those "widgets" be provided by using MDXProvider?

I think you could use remark plugin (it might not necesairly be needed to make it actuial gatsby plugin - gatsby-plugin-mdx does support raw remark plugins (see remarkPlugins option), but this is likely only if you don't to add imports for those widgets

apolopena commented 4 years ago

Yeah I am using an MDXprovider with no individual imports per .md file. I was wondering about timing. I am hoping the transformation via the raw remark plugin would happen before the body node is created so that when I pass the body from the graphql query to the MDXRenderer within the MDXprovider the newly transformed JSX would be there. I Currently import any react components that might be used in the markdown files in the default template in the options for gatsby-plugin-mdx and that works fine.

apolopena commented 4 years ago

I suppose in order to avoid the unit tests and distribution step required in building a remark plugin I could just code all of this into a local gatsby plugin for now. I am still a bit unsure of the timing and placement of the code.

pieh commented 4 years ago

Timing seems to work out nicely - check https://github.com/pieh/i22726

In particular - adding remark plugin (we don't have to wrap it to be gatsby plugin as well): https://github.com/pieh/i22726/blob/fb22bce072855bec72a13d70709fa78260251403/gatsby-config.js#L30 and content of the plugin https://github.com/pieh/i22726/blob/master/remark-plugin/index.js (which is very silly, but does somewhat what you want - turn some arbitrary text into actual components)

The result (together with this input https://raw.githubusercontent.com/pieh/i22726/master/content/blog/hello-world/index.md and this MDXProvider config https://github.com/pieh/i22726/blob/master/wrap-root-element.js#L22) is working: Screenshot 2020-04-02 at 23 59 22

I'm not exactly sure how complex yours will need to be, because trying the sample content

some text here, blah blah blah, an image la la de dah
{"widget":"smartcaption","caption":"The image is described","credit":"by some person"}
more text is here la la la

in https://mdxjs.com/playground/ somewhat merges this as single paragraph, so you would need a way to split this into paragraph for text before the JSON object, then jsx element and then paragraph for text after the JSON object (unless you will force extra newlines before/after those JSON objects) which would result in separate paragraphs and just swapping one with jsx element

apolopena commented 4 years ago

@pieh Wow thanks so much for this awesome, simplified example of the approach I was contemplating! It was easier than I thought and timing was not an issue as you said. I see now that the raw remark plugin can be a local plugin so that is easy. The only part I would have wrestled with was wiring everything together with wrapRootElement in gatsby-browser.js/gatsby-ssr.js and the logic in wrap-root-element.js but that now makes complete sense!

I have another question: I take it this approach runs the plugin/transformation on all pages. What if I only wanted that custom root element for only .md files?

pieh commented 4 years ago

I have another question: I take it this approach runs the plugin/transformation on all pages. What if I only wanted that custom root element for only .md files?

It runs only for mdx content, so it won't be active for anything other than .md/.mdx files (depending how you configure gatsby-plugin-mdx) - the context that MDXProvider creates is consumed only by MDXRenderer.

You can also move the MDXProvider to individual page templates instead of wrapRootElement if you prefer (only requierment is really for MDXPRovider to be above MDXRenderer in component tree)

github-actions[bot] commented 4 years ago

Hiya!

This issue has gone quiet. Spooky quiet. 👻

We get a lot of issues, so we currently close issues after 30 days of inactivity. It’s been at least 20 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open! As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 💪💜

github-actions[bot] commented 4 years ago

Hey again!

It’s been 30 days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it. Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m HUMAN_EMOTION_SORRY. Please feel free to reopen this issue or create a new one if you need anything else. As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks again for being part of the Gatsby community! 💪💜