vernak2539 / astro-rehype-relative-markdown-links

Rehype Plugin for Astro that allows for usage of relative links between markdown files
https://www.npmjs.com/package/astro-rehype-relative-markdown-links
15 stars 4 forks source link

feat: add support for dynamically resolving collection name and/or url path #53

Open techfg opened 7 months ago

techfg commented 7 months ago

Currently, the plugin relies on physical file structure to determine an absolute page path to the linked markdown file. For example, for ./src/content/blog/2023-06-15-post.md with a link to [Cool Stuff](./2023-05-01-post, the transformed url will be /blog/2023-05-01-post because the name of the collection on disk is blog and the filename (or custom slug if present) is used.

This works great when the page paths serving the pages align 1:1 to the physical file structure on disk but does not work when the page paths are dynamically determined within getStaticPaths. For example, getStaticPaths could map the slug for the file to /my-blog/2023/05/01/post. Custom slugs can be used to solve the 2023/05/01/post part but the name of the collection itself still presents an issue because the plugin looks at the name of the collection on disk to add to the absolute path generated.

PR #50 helps address the shortcoming of the collection name part by adding a collections override option to support setting the name of a collection, using it instead of the name on disk. This helps but doesn't get all the way to a full solution.

PR #52 helps eliminate more of the challenges by transforming to relative paths (so that the collection name doesn't matter anymore) but still doesn't solve the issue of getStaticPaths dynamically generating a slug that isn't specified in the markdown file frontmatter itself. In this case, there just isn't a way for the plugin to know what the actual page path would be.

Regardless of whether #49, #50 and/or #52 are merged, would like to propose that an option is added where a callback would be invoked to allow the user to build the path. This would be analagous to getStaticPaths and likely most (if not all) of the code in that method could be used in the callback.

The callback could receive:

  1. The current markdown file path
  2. The frontmatter of the current markdown file
  3. The linked markdown file path
  4. The frontmatter of the linked markdown file

For example, the following (or something similar) could be added to options:

options = {
  /* 
    1. The two (2) file paths could possibly be URL objects instead of strings
    2. The two (2) frontmatter properties could be the full GrayMatterFile 
    itself or possibly just the `data` property (Record<string, any>) 
  */
  resolvePath = ({
    currentFilePath: string,
    currentFileFrontmatter: matter.GrayMatterFile<I = matter.Input>,
    linkedFilePath: string,
    linkedFileFrontmatter: matter.GrayMatterFile<I = matter.Input>
  }) => string
}

In addition to the above, depending on the outcome of #52, if collectionBase:name remains, the name option could accept a function as well for dynamically resolving the name of a collection when generating the full path isn't needed but instead only the name of the collection.