Open alexbouchardd opened 9 months ago
While not specifically mentioned in the Markdoc documentation of variables, it may be the case that the format doesn’t support variables in code blocks and inline code snippets. For example they do say:
Markdoc doesn't support passing variables to certain nodes, such as the
href
of alink
Node. Instead, pass your variable to thehref
attribute of a customlink
Tag.
From playing around with the Markdoc playground it looks like the following should work:
Inline {% code %}{% $test %}{% /code %} variable.
```js
{% $test %}
But regular inline code backticks do not render variables.
Playground example: https://markdoc.dev/sandbox?mode=preview&c=LS0tCnRpdGxlOiBUZXN0Ci0tLQoKSW5saW5lIHslIGNvZGUgJX17JSAkbWFya2RvYy5mcm9udG1hdHRlci50aXRsZSAlfXslIC9jb2RlICV9IHZhcmlhYmxlLgoKYGBganMKeyUgJG1hcmtkb2MuZnJvbnRtYXR0ZXIudGl0bGUgJX0KYGBgCgpJbmxpbmUgYHslICRtYXJrZG9jLmZyb250bWF0dGVyLnRpdGxlICV9YCB2YXJpYWJsZS4%253D
Good catch! Although I do know from the previous project (I'm porting my docs over to Astro) that the variables are supposed to render in fences, and the playground link also supports that.
Do you know why the workaround or replaceAll
on entry.body
doesn't work? That would also be the "solution" for code backticks not interpolating.
I don’t think render()
depends on entry.body
at all, so mutating it won’t have any impact.
Maybe one option would be to provide an Astro component to render the code blocks?
I’m not that familiar with Markdoc, but if this is supported you could do the find/replace in the Astro component maybe?
---
// src/components/MarkdocFence.astro
const VARIABLES = {
// ...
};
let html = await Astro.slots.render('default');
for (const key of Object.keys(VARIABLES)) {
html = html.replaceAll(`{% $${key} %}`, VARIABLES[key]);
}
---
<Fragment set:html={html} />
I don’t think render() depends on entry.body at all, so mutating it won’t have any impact.
Right, that makes sense and is consistent with what I've seen. That's a good approach. I'll validate if it works and update here. Nonetheless, I think this should be considered a workaround.
That worked as a workaround. For reference, instead of providing a component for the render block, I wrapped the whole rendered Markdoc output.
---
const entry = await getEntryBySlug("api", section);
const { Content } = await entry.render();
---
<Markdoc>
<Content />
</Markdoc>
---
import VARIABLES from "@/variables";
let html = await Astro.slots.render('default');
for (const key of Object.keys(VARIABLES)) {
html = html.replaceAll(`{% $${key} %}`, VARIABLES[key]);
}
---
<Fragment set:html={html} />
Thanks @delucis !
Is this a limitation in markdoc?
No it is not, as per their playground and reproduction it's an issue with Astro Markdoc / shiki
Thanks for clarifying! I couldn't make it out from the previous comments.
Astro Info
If this issue only occurs in one browser, which browser is a problem?
No response
Describe the Bug
I've noticed that the variables in Markdoc only render as expected when used in plain text. Fence, code, headers, etc do not render the variable value.
The fence one is especially curious since the variable doesn't render ONLY when shiki markdoc plugin is enabled
markdoc.config.mjs
some-template.mdoc
Added as a screenshot cause I can't do code block in a code block in Github
Given the above, the first
{% $test %}
rendershello-world
the second apre
with{% $test %}
.If I comment out
shiki()
it both rendershello-world
as expectedAdditionally, no variables render if used in a other nodes
What's the expected result?
Using a variable a in Markdoc renders the variable value regardless of where the variable is. Fence renders variables when Shiki is enabled.
Link to Minimal Reproducible Example
https://stackblitz.com/edit/github-osnyth?file=src%2Fcontent%2Ftemp%2Fexample.mdoc
Participation
Work Around?
In the meantime, this is a significant blocker, is there any workaround to recommend?
I've tried the following but no luck, then
render()
seems to ignore the updatedbody
. The string interpolation work thought, if Iconsole.log(entry.body)
the string has the variables properly replaced.