zce / velite

Turns Markdown / MDX, YAML, JSON, or others into app's data layer with Zod schema.
http://velite.js.org
MIT License
476 stars 23 forks source link

raw.flattenPath equivalent #34

Closed capsloq closed 8 months ago

capsloq commented 8 months ago

First of all great substitute for contentlayer thank you for that. I am testing out velite by migrating a contentlayer project.

In contentlayer my slugs were based on the filepath. For a nested MDX file in e.g. content/firstfolder/secondfolder/test.mdx that meant the slug would be /firstfolder/secondfolder/test

To achieve that in contentlayer we had raw.flattenedPathlike

const computedFields: ComputedFields = {
  slug: {
    type: "string",
    resolve: (doc) => `/${doc._raw.flattenedPath}`,
  },

I did read the velite documentation but how would that be achieved in velite? I understand you can either use .transform for collection based computed fields or prepare for all collections.

If there is a solutions to this might consider adding it to the docs

Thank you

capsloq commented 8 months ago

Answering my own Question:

There is a context object as an argument within transform:

 schema: s
        .object({
          title: s.string().max(99),
          ...

        })
        .transform((data, ctx) => ({ ...data,
          // computed fields 
          permalink: `/${data.slug}`,
          fileInfo: ctx.meta.file.path,
          fileInfo2: ctx.meta.file.basename,
          fileInfo3: ctx.meta.file.dirname,
          fileInfo4: ctx.meta.file.extname,

        }))

Still suggesting to add an example to the docs for "file based slugs" so folks migrating from contentlayer have it easier

zce commented 8 months ago

Yup, but it is recommended to use file.stem, which is more similar to flattenedPath.

refer to VFile.stem for more details.

zce commented 8 months ago
path: s.path()
// => flattened path, e.g. 'posts/2021-01-01-hello-world'

https://velite.js.org/guide/velite-schemas#s-path