Skip to content

[Design issues] Edit frontmatter could be complicated #519

@Mister-Hope

Description

@Mister-Hope

Editing frontmatter may be complicated with current APIs.

Though we are providing a extendsPageOption hook to provide a default frontmatter (user frontmatter can overide them). But there can be situations, where plugins and theme try to add frontmatter content or even editing them after reading the content with some logic.

Just as an example, I would want "plugin A" to autocomplete title for homepages, so that I would probably use extendsPageData to do so:

export default {
  extendsPageData: ({ frontmatter}) => {
    if(frontmatter.home && !frontmatter.title) {
      // here I want to set `frontmatter,titlte` as 'home'
    }
  }
}

(This is just an example, and it could be done extendsPageOptions because we can inffer homepage by reading siteConfig.locales, but there are other situations that we must perform something after getting page)

And in the current API, there is no way to safely achieve this:

We can only delete frontmatter or editing using the below way

export default {
  extendsPageData: ({ frontmatter}) => {
    if(frontmatter.home) {
      frontmatter.title = frontmatter.title || 'home'
 
     // convert v1 format
     if(frontmatter.actionText && frontmatter.actionLink) {
       frontmatter.actions = [{ text: frontmatter.actionText, link: frontmatter.actionLink}]

       delete frontmatter.actionText
       delete frontmatter.actionLink
      }
    }
   
   return {};
  }
}

All plugins must edit frontmatter as above way to not effect others.

if theme or other plugins excuted later are setting a new frontmatter like this, all fronter edits will be lost as frontmatter in Page never changed, and the following is creating a new frontmatter object.

export default {
  extendsPageData: ({ frontmatter}) => ({
    frontmatter: {
      ...frontmatter,
      // new data here
     }
  }}
}

So that

// original frontmatter is `{ user: 'content' }`

// pluginA
export default {
  extendsPageData: ({ frontmatter}) => ({
    frontmatter: {
      ...frontmatter,
      plugin: 'a'
     }
  }}
}

// theme
export default {
  extendsPageData: ({ frontmatter}) => ({
    frontmatter: {
      ...frontmatter,
      theme: 'b'
     }
  }}
}

// finally frontmatter is `{ user: 'content', theme: 'b' }

And if a plugin developer write something like this. user frontmatter will be fully erased.

// original frontmatter is `{ user: 'content' }`

// pluginA
export default {
  extendsPageData: () => ({
    frontmatter: {
      plugin: 'a'
     }
  }}
}

// finally frontmatter is `{ plugin: 'a' }

Since the extendsPageData courage people to return new data, I think we can try to make some improvement here to avoid some plugins or theme earsing all edits made before.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions