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

make parsed md/mdx frontmatter available to plugins #5099

Closed
1 task
stefanprobst opened this issue Oct 15, 2022 · 5 comments · Fixed by #5687
Closed
1 task

make parsed md/mdx frontmatter available to plugins #5099

stefanprobst opened this issue Oct 15, 2022 · 5 comments · Fixed by #5687
Assignees
Labels
- P2: nice to have Not breaking anything but nice to have (priority)

Comments

@stefanprobst
Copy link

What version of astro are you using?

1.5.0

Are you using an SSR adapter? If so, which one?

none

What package manager are you using?

npm

What operating system are you using?

linux

Describe the Bug

currently, remark/rehype plugins are only allowed to add additional fields to vfile.data.astro.frontmatter, however the parsed frontmatter from markdown/mdx sources files is not made available to plugins (i.e. vfile.data.astro.frontmatter is passed as an empty object).

Link to Minimal Reproducible Example

https://github.com/stefanprobst/issue-astro-md-frontmatter/blob/main/astro.config.mjs

Participation

  • I am willing to submit a pull request for this issue.
@matthewp
Copy link
Contributor

matthewp commented Nov 4, 2022

@bholmesdev is this possible?

@matthewp matthewp added the - P2: nice to have Not breaking anything but nice to have (priority) label Nov 4, 2022
@stefanprobst
Copy link
Author

here you could use vfile-matter (instead of gray-matter) which will attach parsed frontmatter to vfile.data.matter, or manually attach the parsed frontmatter returned by gray-matter somewhere on vfile.data before calling the unified processor with the vfile.

@bholmesdev
Copy link
Contributor

bholmesdev commented Nov 4, 2022

@matthewp It should be, and I've proposed a couple solutions in our discord #dev channel previously. I sadly haven't landed on an API everyone was happy with.

One suggestion was to add user frontmatter to the frontmatter object instead of leaving it empty. This would be a breaking change since, instead of allowing user frontmatter to override conflicting remark / rehype frontmatter, it would now be reversed.

i.e. if a user has this:

---
title: My blog post
---

And your plugin specifies this:

...
data.astro.frontmatter.title = "My title override"
  • With today's API: Your frontmatter would "win" over your plugin's frontmatter.
  • With new proposed API: The plugin would override an existing astro.frontmatter.title property, so the plugin would "win" over your frontmatter.

Another non- breaking option would be to add a readonly version of the user's frontmatter as a separate property. Something like data.astro.userFrontmatter, which you can read from to specify data.astro.frontmatter. We'd definitely need to bikeshead better naming though.

Personally, I've been setting this aside as a 2.0 concern to avoid over-complicating the API, and also investigating how our Content Schemas RFCs can address this in a more predictable way. Though if userFrontmatter (or some equivalent) is worth prototyping, I'll submit a draft PR!

@bholmesdev bholmesdev self-assigned this Nov 4, 2022
@christian-hackyourshack
Copy link
Contributor

christian-hackyourshack commented Nov 30, 2022

I am very much in favor to give injectedFrontmatter the possibility to override pageFrontmatter, but then, also give the injecting plugin the pageFrontmatter as input, so the plugin can responsibly choose, whether it wants to override something.

In the above example, it would be as easy as using Nullish coalescing assignment

data.astro.frontmatter.title ??= "My title override"

One of my archetypical use cases is 'relative images in frontmatter': My users can reference images in frontmatter, and they may use relative paths. My plugin would take care of resolving those paths, so I do not have to worry about that in the code of my website. Currently I have 2 choices, I can either write the resolved paths into a second frontmatter property (leaving me with the trouble to always remember to use frontmatter.author.resolvedAvatar) or I can do the resolution of frontmatter paths in my markdown layout (which I opted for now, but that separates resolution of paths in the markdown from the resolution in frontmatter, which is also ugly for maintenance reasons).

Developers are not only creative, they are actual creators. A framework should allow them to climb quickly but not get into their way. In this case we think too German: Where we think, we are always responsible to protect others from doing something stupid. Personally, I think it is enough to make doing the-not-so-stupid thing the more obvious option.

I could create a PR, that would prefill frontmatter with pageFrontmatter in the VFile, that is passed to plugins and then we would probably not need a merge afterwards anymore (but that we could discuss).

@bholmesdev
Copy link
Contributor

@christian-hackyourshack Very much in favor of that change! Still, for the reasons I outlined in my previous comment, this would be a breaking change we'd have to delay to a major 2.0 release. Partially why I wanted to explore short term solutions like a separate readonly userFrontmatter that we could release in a minor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
- P2: nice to have Not breaking anything but nice to have (priority)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants