如何让11ty FrontMatter中的Shortcode正常渲染?
问题:让11ty FrontMatter中的Shortcode正常渲染
我用11ty搭配Decap CMS开发客户网站,在FrontMatter中设置了多个字段用于插入Markdown内容。目前通过markdown-it过滤器渲染Markdown效果正常,但自定义的Shortcode(比如用于插入YouTube iframe的短代码)在Markdown正文里能正常解析,放到FrontMatter的字段中就失效了。如何让FrontMatter中的Shortcode也能被正确渲染?
当前配置
.eleventy.js
// YouTube嵌入短代码 eleventyConfig.addNunjucksShortcode("youtube", (classes, videoURL, title, caption) => { const url = new URL(videoURL); const id = url.searchParams.get("v"); var caption= mdSetup.render(caption); return ` <figure class= "${classes}"> <iframe src="https://www.youtube-nocookie.com/embed/${id}" title="${ title ? ` for ${title}` : "" }" frameborder="0" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> <figcaption class="caption"> <span class="wrapper">${caption}</span> </figcaption> </figure> `; }); // 处理Markdown的过滤器 eleventyConfig.addFilter("in_markdownify", (markdownString) => mdSetup.renderInline(markdownString) );
包含YAML FrontMatter的.md文件
--- title: Testing Image Compression layout: layouts/banners.njk banners: - bg: - label: White Background / Purple text name: whitebg imgstyle: - label: Green text / Purple Shadow value: img-green id: banner1 boxes: - type: dc-box left: Test right: > {% youtube "Class" , "https://www.youtube.com/watch?v=JC7MNybwnTA" , "Comment" , "Caption" %} ## MARKDOWN ---
模板文件(banners.njk)
<div class="doublec-box text"> <div class="leftc"> {{ box.left | markdownify | safe}} </div> <div class="rightc"> {{ box.right | markdownify | safe}} </div> </div>
当前HTML输出
<div class="doublec-box text"> <div class="leftc"> <p>Test</p> </div> <div class="rightc"> <p> {% youtube “undefined” , “<a href="https://www.youtube.com/watch?v=JC7MNybwnTA">https://www.youtube.com/watch?v=JC7MNybwnTA</a>” , “Dead White man’s Clothes x Atmos” , “” %} </p> <h2 id="markdown" tabindex="-1">MARKDOWN</h2> </div> </div>
期望HTML输出
<p><figure class= "undefined"> <iframe src="https://www.youtube-nocookie.com/embed/JC7MNybwnTA" title=" title" frameborder="0" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> <figcaption class="caption"> <span class="wrapper"></span> </figcaption> </figure></p>
解决方案
FrontMatter中的内容默认只会被解析为静态文本,不会触发Nunjucks的Shortcode渲染逻辑。要实现需求,需要先让Nunjucks编译内容执行Shortcode,再用markdown-it处理Markdown格式。
步骤1:新增复合过滤器
在.eleventy.js中添加一个新过滤器,先调用Nunjucks渲染Shortcode,再处理Markdown:
// 先渲染Shortcode,再处理Markdown的复合过滤器 eleventyConfig.addFilter("renderWithShortcodes", function(content) { // 获取当前Nunjucks环境实例 const nunjucksEnv = this.nunjucksEnv; // 第一步:执行Shortcode编译 const shortcodeRendered = nunjucksEnv.renderString(content); // 第二步:处理Markdown格式 return mdSetup.render(shortcodeRendered); });
步骤2:替换模板中的过滤器
把模板里原来的markdownify过滤器换成新的renderWithShortcodes:
<div class="doublec-box text"> <div class="leftc"> {{ box.left | renderWithShortcodes | safe}} </div> <div class="rightc"> {{ box.right | renderWithShortcodes | safe}} </div> </div>
注意事项
- 确保
mdSetup变量在过滤器中可正常访问(如果是局部变量,需要在过滤器内部正确初始化或引入) - 如果部分FrontMatter字段只需要渲染Shortcode不需要Markdown,可以单独创建一个仅编译Shortcode的过滤器
- 在Decap CMS中输入Shortcode时,注意引号的转义问题,避免语法错误
内容的提问来源于stack exchange,提问作者vermar
相关产品推荐
相关产品推荐

