You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 19:14:52