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

Not clear how to modify frontmatter programmatically #3930

Closed
carsakiller opened this issue Jul 28, 2023 · 5 comments · Fixed by #3988
Closed

Not clear how to modify frontmatter programmatically #3930

carsakiller opened this issue Jul 28, 2023 · 5 comments · Fixed by #3988
Labels
improve or update documentation Enhance / update existing documentation (e.g. add example, improve description, update for changes)

Comments

@carsakiller
Copy link
Contributor

📚 Subject area/topic

Markdown

📋 Page(s) affected (or suggested, for new content)

https://docs.astro.build/en/guides/markdown-content/#modifying-frontmatter-programmatically

📋 General description or bullet points (if proposing new content)

I was trying to add a “modified time” to the bottom of the MDX articles on my website. I found the modifying frontmatter programmatically section in the Astro docs.

So I created a simple remark plugin modifiedTime.mjs that gets a file's modified time from git:

import { execSync } from "child_process";

export function modifiedTime() {
  return function (tree, file) {
    const filepath = file.history[0]; // Not sure this is the best place to get the filepath...
    const result = execSync(`git log -1 --pretty="format:%cI" ${filepath}`);
    file.data.astro.frontmatter.lastModified = result.toString();
  };
}

I then modified my Astro config, as per the documentation:

import { defineConfig } from "astro/config";

import mdx from "@astrojs/mdx";
import { modifiedTime } from "./src/plugins/modifiedTime.mjs";

// https://astro.build/config
export default defineConfig({
  integrations: [mdx()],
  markdown: {
    remarkPlugins: [modifiedTime],
  },
});

And finally, in my page that renders the markdown (simplified):

---
import { getCollection } from "astro:content";

import Layout from "../../layouts/WikiArticle.astro";
import type { CollectionEntry } from "astro:content";
import dayjs from "../../services/time";

export const getStaticPaths = async () => {
  const articles = await getCollection("wiki");
  return articles.map((article) => {
    return { params: { slug: article.slug }, props: { article } };
  });
};

const { article } = Astro.props;
const { Content, headings } = await article.render();
const slug = article.data.title.toLowerCase().replaceAll(" ", "-");

export interface Props {
  article: CollectionEntry<"wiki">;
}

const modifiedTime = article.data.lastModified ?? "???";
---

<Layout article={article} headings={headings}>
  <Content  />
  <div class="modified-timestamp">
    <p>Last Modified: {modifiedTime}</p>
  </div>
</Layout>

Note that in this page, I am using getStaticPaths(), which I learned from the content-collections page. This is where I got lost. Because my content is in MDX files, I was reading the MDX solution - but after hours of not being able to figure out why it wasn't working, I discovered that I actually need to follow modifying frontmatter with remark.

Using the below now works:

---
import { getCollection } from "astro:content";

import Layout from "../../layouts/WikiArticle.astro";
import type { CollectionEntry } from "astro:content";
import dayjs from "../../services/time";

export const getStaticPaths = async () => {
  const articles = await getCollection("wiki");
  return articles.map((article) => {
    return { params: { slug: article.slug }, props: { article } };
  });
};

const { article } = Astro.props;
- const { Content, headings } = await article.render();
+ const { Content, headings, remarkPluginFrontmatter } = await article.render();
const slug = article.data.title.toLowerCase().replaceAll(" ", "-");

export interface Props {
  article: CollectionEntry<"wiki">;
}

- const modifiedTime = article.data.lastModified ?? "???";
+ const modifiedTime = remarkPluginFrontmatter.lastModified ?? "???"
---

<Layout article={article} headings={headings}>
  <Content  />
  <div class="modified-timestamp">
    <p>Last Modified: {modifiedTime}</p>
  </div>
</Layout>

I spent hours trying to get this to work because, oddly enough, sometimes it DID work. When saving the astro.config.mjs file, vite would restart and the current page I was on would actually correctly display the modified time at the bottom of the page. However, killing the dev server with CTRL + C and running npm run dev again (or refreshing the page) does not work, with the modified time being ??? (undefined)

🖥️ Reproduction in StackBlitz (if reporting incorrect content or code samples)

It isn't incorrect, just not clear. There should be some sort of warning in the https://docs.astro.build/en/guides/markdown-content/#modifying-frontmatter-programmatically section perhaps that directs users to https://docs.astro.build/en/guides/content-collections/#modifying-frontmatter-with-remark

@carsakiller carsakiller added the improve or update documentation Enhance / update existing documentation (e.g. add example, improve description, update for changes) label Jul 28, 2023
@TheOtterlord
Copy link
Member

Thanks for reporting this! Adding some additional notes:

I know the reading time recipe includes instructions on how to do this, and this section should definitely include that too. This follows the shape of the reading time recipe pretty closely. Maybe there's an opportunity to unify these two? Also, I'm not sure if this is an outdated example, or if there's a reason to do this, but as far as I know there's no reason to use the MDX remarkPlugins argument over extending the markdown config.

@carsakiller
Copy link
Contributor Author

Ah, yes, now reading the reading time recipe, it is very similar to what I was trying to do here and would've cleared this up pretty easily.

I could contribute my own recipe for adding in the last modified time of an article from Git (or filesystem), however, seeing as it would be very similar to the "reading time" recipe, perhaps it would be best to "generic-ify” the problem instead? Maybe there is a way to add an article that explains the general instructions for loading your content files at build time, doing some form of processing, modifiying the frontmatter, and then accessing the modified frontmatter in your dynamic page.

@sarah11918
Copy link
Member

Hey @carsakiller , thanks for this detailed feedback! 🙌

I know we made reading time a separate recipe and removed it from that page so that we could just link to it instead of adding more specific content to that page. It sounds like there still might be some duplication of content and therefore some streamlining that can be done.

Firstly, I think we'd love a recipe for adding the last modified time of an article! I know the process is similar, but with recipes, people are looking for very specfic things to build, and a reader won't necessarily make the connection that the two are related. So having both is helpful!

We also have an audit of that whole Markdown/MDX page coming for v3 because it was written before content collections existed. And, as you've discovered, that means it sometimes requires you NOT to be on the MDX page (even if you're using MDX!) to get the best info.

There should be some sort of warning in the docs.astro.build/en/guides/markdown-content/#modifying-frontmatter-programmatically section perhaps that directs users to docs.astro.build/en/guides/content-collections/#modifying-frontmatter-with-remark

In the short term, I think you're right. A link between the two sections would be helpful (and, will be helpful when we get around to reorganizing/consolidating docs)

Are you interested in making a PR for this? This would be a great quick addition to the docs!

@carsakiller
Copy link
Contributor Author

a reader won't necessarily make the connection that the two [recipes] are related.

I know I didn't 😄. Okay, I'll look at adding a recipe for adding in the modified time! Astro has been hugely helpful and easy to use, so it is the least I could do. I suppose a good part of why it is so easy is because the documentation is so well done – you guys have done a great job!

@sarah11918
Copy link
Member

We couldn't do it without our amazing community members stepping up and keeping us honest, like you! Happy to have you on Team Docs! 💜

yanthomasdev added a commit that referenced this issue Jul 31, 2023
* add: note to direct users to modifiyng frontmatter with remark

Closes #3930

* more direct wording

---------

Co-authored-by: Sarah Rainsberger <[email protected]>
Co-authored-by: Yan Thomas <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
improve or update documentation Enhance / update existing documentation (e.g. add example, improve description, update for changes)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants