-
Notifications
You must be signed in to change notification settings - Fork 96
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
Can the frontmatter be dynamic? #287
Comments
This isn't currently possible, front matter is expected to be static. You could just export them, they will still be available in the document if needed: <script context='module'>
import coverimg from '$assets/demopost/cover.png';
import thumbnailimg from '$assets/demopost/thumbnail.png';
export { coverimg, thumbnailimg };
</script> |
I have hit a need for something like this a few times also, it would be useful if there was hooks to manipulate the metadata export during the transformation so we could so something like this: ---
title: My lovely article
author: Dr. Fabuloso the Fabulous
coverimage: some-image.jpg
coverimageAlt: Cool coverphoto
--- <script context="module">
import coverimg from "$assets/demopost/some-image.jpg"
export let metadata = {
title: "My lovely article",
author: "Dr. Fabuloso the Fabulous",
coverimage: coverimg,
coverimageAlt: "Cool coverphoto"
};
</script> Would allow us to use this data inside layout files |
I guess we could merge all exports from the ---
title: My lovely article
author: Dr. Fabuloso the Fabulous
coverimage: some-image.jpg
coverimageAlt: Cool coverphoto
--- <script context="module">
import coverimage from "$assets/demopost/some-image.jpg"
export { coverimage };
</script> Another alternative is just to pass all exports from context module down as props. I'll have to think about this one. |
This already works: ---
title: My lovely article
author: Dr. Fabuloso the Fabulous
coverimageAlt: Cool coverphoto
---
<script context="module">
import coverimage from "$assets/demopost/some-image.jpg"
metadata.coverimage = coverimage;
</script>
Blog post content |
@babichjacob Just tested yes it does!! Thanks |
What is the thinking on this, is there a reasonable way to make it easier, or is the current situation okay? |
I want to automatically convert this: ---
title: My lovely article
coverimage: ./testing.jpg
coverimageAlt: Cool coverphoto
--- into this: <script context="module">
import ___ASSET___0 from "./testing.jpg";
export const metadata = {
title: "My lovely article",
coverimage: ___ASSET___0,
coverimageAlt: "Cool coverphoto",
};
const { title, coverimage, coverimageAlt } = metadata;
</script> I managed to figure this out with a simple svelte preprocessor: // svelte.config.js
import preprocess from "svelte-preprocess";
import { mdsvex } from "mdsvex";
import adapterStatic from "@sveltejs/adapter-static";
import { parse, walk } from "svelte/compiler";
import MagicString from "magic-string";
/** @returns {import("svelte/types/compiler/preprocess").PreprocessorGroup} */
function plugin() {
return {
async markup({ content, filename }) {
if (!filename.endsWith(".svelte.md")) return { code: content };
const s = new MagicString(content);
const ast = parse(content, { filename });
walk(ast.module, {
enter(node) {
if (!(node.type === "VariableDeclarator" && node.id.name === "metadata")) return;
for (const property of node.init.properties) {
if (property.key.value === "coverimage") {
const importText = `import ___ASSET___0 from "${property.value.value}";`;
s.appendLeft(ast.module.content.start, importText);
s.overwrite(property.value.start, property.value.end, "___ASSET___0");
console.log(s.toString());
}
}
},
});
return {
code: s.toString(),
map: s.generateMap(),
};
},
};
}
/** @type {import('@sveltejs/kit').Config} */
const config = {
extensions: [".svelte", ".svelte.md"],
preprocess: [mdsvex({ extensions: [".svelte.md"] }), plugin(), preprocess()],
kit: {
target: "#svelte",
adapter: adapterStatic(),
},
};
export default config; This works but is pretty fragile, I wonder would an API like the following be better: /** @type {MdsvexOptions} */
export const mdsvexConfig = {
extensions: [".svelte.md"],
frontmatter: {
transform: {
coverimage(value) {
return {
newValue: "coverimage",
import: `import ___ASSET___0 from "${value}"`,
};
},
},
},
}; |
Interesting. I'll have a think about this. We could even do something simpler for the common case and have some default handling for certain things: /** @type {MdsvexOptions} */
export const mdsvexConfig = {
extensions: [".svelte.md"],
frontmatter: {
types: {
coverimage: 'image-import'
},
},
}; That said we could also just detect this automatically (for images) and enable/ disable based on an boolean options, or do it based on extension instead: /** @type {MdsvexOptions} */
export const mdsvexConfig = {
extensions: [".svelte.md"],
frontmatter: {
types: [
/\.jpg$|\.png$/, 'image-import' // or a function to handle it
],
},
}; In line with other parts of the design for v1, I'm likely to handle this in an 'official' plugin: import { transformFrontmatter } from 'mdsvex/plugins';
/** @type {MdsvexOptions} */
export const mdsvexConfig = {
extensions: [".svelte.md"],
plugins: [
transformFrontmatter({
transform: {
// not sure if a matcher on the value or a handler for the prop name is most appropriate, probably name based
match: /\.jpg$|\.png$/,
handler: 'import' // builtin or a function to handle it
}
})
],
}; |
I thought a lot about communication between the markdown file and the layout file. I went about this a little differently, I went into the mdsvex code and added
then in my
// this works and gets updated from the frontmatter
export let title = 'default title';
// this works for dynamically setting the title
let bridge = {
setTitle(value) {
title = value;
}
} this way I can call the setTitle from the markdown file and dynamically update the title based on information I only have in the markdown. I only did this to see if it would work. I don't know if it's a good idea, I want to get thoughts from people more experienced with svelte than I am. Should this be a feature in mdsvex (allowing 2-way communication through the "markdown slot", instead of just passing things one way) EDIT: actually, I see the solution babichjacob suggested works for setting the title too. |
Hey there folks, I'm sorry for reviving an older issue but I did not understand the solution here (I should also mention that I'm learning SvelteKit at the same time).
when I consume this I'm getting an error: My I guess I'm wrong on that, so what is the solution for the above? Thanks |
Hi, I have a blog created with MDsveX written in Sveltekit and deployed on Netlify. It works amazingly.
But whenever I want to use images I have to use links in the blog post. I want to be able to import photos directly into the .svx files. Here's an example of what I want to do:
Is something like this possible?
E: Can those variables,
coverimg
andthumbnailimg
be exported and then imported along with frontmatter, because that would solve my problem as well?The text was updated successfully, but these errors were encountered: