nuxt / content

The file-based CMS for your Nuxt application, powered by Markdown and Vue components.
https://content.nuxt.com
MIT License
3.12k stars 623 forks source link

Allow define the parent element in prose #2018

Open maximepvrt opened 1 year ago

maximepvrt commented 1 year ago

Is your feature request related to a problem? Please describe

Currently, the image is embedded within a <p> element and cannot be removed, unless using a content:file:after hook.

Describe the solution you'd like

add an option in Prose to define the parent element or remove that (if defined to null)

Additional context

I use nuxt-content to build mjml emails and image can't be in a mjml-text, a<ul> can be only on a mjml-text

My proses transforms <p> => <mjml-text> <img> => <mjml-image>

davestewart commented 1 year ago

Couldn't you just override ProseP with a render function and check what's in the slot?

maximepvrt commented 1 year ago

I don't see how to do that in ProseP but this solution does not allow to add a <p> tag around a list (<ul>) for example.

davestewart commented 1 year ago

You could as you mention walk the AST in the after hook and modify the P tags in there.

In fact, it seems a remark plugin exists to do just this:

maximepvrt commented 1 year ago

yes I manage to do it very well with the hook, but natively managing the nesting of the elements between them would be practical and would avoid using a nitro plugin.

export default defineNitroPlugin((nitroApp) => {
    nitroApp.hooks.hook('content:file:afterParse', (file) => {
        if (file._id.endsWith('.md')) {
            file.body.children = file.body.children.map(function(c: any) {
                if (c.tag == 'p' && c.children.length == 1 && c.children[0].tag == 'img') {
                    return c.children[0];
                }
                if (c.tag == 'ul') {
                    return {
                        type: 'element',
                        tag: 'p',
                        props: {},
                        children: [c],
                    };
                }
                return c;
            });
        }
    })
})