[{"data":1,"prerenderedAt":542},["ShallowReactive",2],{"sidebar-page":3,"page-\u002Fmarkdown-nunjucks-usage-2026-09-18":4},null,{"id":5,"title":6,"author":7,"body":8,"cover":3,"date":531,"description":532,"extension":396,"meta":533,"navigation":53,"path":534,"seo":535,"stem":536,"tags":537,"__hash__":541},"content\u002Fmarkdown-nunjucks-usage-2026-09-18.md","关于在 Markdown 中嵌入 Nunjucks 组件的说明","AeYunDian",{"type":9,"value":10,"toc":522},"minimark",[11,20,25,28,31,61,64,67,71,74,76,96,98,105,108,111,115,118,120,152,154,157,164,168,171,173,192,194,197,200,206,209,211,230,232,235,240,244,256,258,300,302,425,429,440,447,449,464,466,484,491,498,512,516,519],[12,13,14,15,19],"p",{},"本站的 ",[16,17,18],"code",{},".md"," 文件由 Eleventy 的 Nunjucks 引擎在构建时编译。正文中的 Nunjucks 模板语法会被解析执行，组件以 macro 的形式调用。现将使用方法说明如下。",[21,22,24],"h2",{"id":23},"一基本用法","一、基本用法",[12,26,27],{},"在 frontmatter 之后，正文中直接书写 Nunjucks 语法即可。使用组件前，需要先从组件文件导入对应的 macro：",[12,29,30],{},"{% raw %}",[32,33,38],"pre",{"className":34,"code":35,"language":36,"meta":37,"style":37},"language-njk shiki shiki-themes monokai","{% from \"components\u002Fbutton.njk\" import button %}\n\n{{ button({ text: \"阅读全文\", href: \"\u002Fposts\u002Fhello\u002F\", type: \"primary\" }) }}\n","njk","",[16,39,40,48,55],{"__ignoreMap":37},[41,42,45],"span",{"class":43,"line":44},"line",1,[41,46,47],{},"{% from \"components\u002Fbutton.njk\" import button %}\n",[41,49,51],{"class":43,"line":50},2,[41,52,54],{"emptyLinePlaceholder":53},true,"\n",[41,56,58],{"class":43,"line":57},3,[41,59,60],{},"{{ button({ text: \"阅读全文\", href: \"\u002Fposts\u002Fhello\u002F\", type: \"primary\" }) }}\n",[12,62,63],{},"{% endraw %}",[12,65,66],{},"渲染结果是一个带样式的按钮链接。正文中的 Nunjucks 语法与 Markdown 可以混用，不会相互干扰。",[21,68,70],{"id":69},"二条件渲染","二、条件渲染",[12,72,73],{},"Nunjucks 的 if 标签用于根据 frontmatter 或站点数据决定是否输出某段内容。",[12,75,30],{},[32,77,79],{"className":34,"code":78,"language":36,"meta":37,"style":37},"{% if description %}\n\u003Cp>本文摘要：{{ description }}\u003C\u002Fp>\n{% endif %}\n",[16,80,81,86,91],{"__ignoreMap":37},[41,82,83],{"class":43,"line":44},[41,84,85],{},"{% if description %}\n",[41,87,88],{"class":43,"line":50},[41,89,90],{},"\u003Cp>本文摘要：{{ description }}\u003C\u002Fp>\n",[41,92,93],{"class":43,"line":57},[41,94,95],{},"{% endif %}\n",[12,97,63],{},[12,99,100,101,104],{},"实际效果：本页的 ",[16,102,103],{},"description"," 有值，所以下面的摘要会显示出来。",[12,106,107],{},"{% if description %}",[12,109,110],{},"本文摘要：{{ description }}",[21,112,114],{"id":113},"三循环渲染","三、循环渲染",[12,116,117],{},"for 标签用于遍历数组，比如站点导航、文章标签。",[12,119,30],{},[32,121,123],{"className":34,"code":122,"language":36,"meta":37,"style":37},"\u003Cul>\n{% for item in site.navigation %}\n  \u003Cli>\u003Ca href=\"{{ item.url }}\">{{ ui.nav[item.key] }}\u003C\u002Fa>\u003C\u002Fli>\n{% endfor %}\n\u003C\u002Ful>\n",[16,124,125,130,135,140,146],{"__ignoreMap":37},[41,126,127],{"class":43,"line":44},[41,128,129],{},"\u003Cul>\n",[41,131,132],{"class":43,"line":50},[41,133,134],{},"{% for item in site.navigation %}\n",[41,136,137],{"class":43,"line":57},[41,138,139],{},"  \u003Cli>\u003Ca href=\"{{ item.url }}\">{{ ui.nav[item.key] }}\u003C\u002Fa>\u003C\u002Fli>\n",[41,141,143],{"class":43,"line":142},4,[41,144,145],{},"{% endfor %}\n",[41,147,149],{"class":43,"line":148},5,[41,150,151],{},"\u003C\u002Ful>\n",[12,153,63],{},[12,155,156],{},"输出为：",[32,158,162],{"className":159,"code":122,"language":161},[160],"language-text","text",[16,163,122],{"__ignoreMap":37},[21,165,167],{"id":166},"四嵌入组件","四、嵌入组件",[12,169,170],{},"本站提供的组件均可在正文中直接调用。先导入，再调用：",[12,172,30],{},[32,174,176],{"className":34,"code":175,"language":36,"meta":37,"style":37},"{% from \"components\u002Falert.njk\" import alert %}\n\n{{ alert({ type: \"info\", title: \"提示\", content: \"这是一条信息。\" }) }}\n",[16,177,178,183,187],{"__ignoreMap":37},[41,179,180],{"class":43,"line":44},[41,181,182],{},"{% from \"components\u002Falert.njk\" import alert %}\n",[41,184,185],{"class":43,"line":50},[41,186,54],{"emptyLinePlaceholder":53},[41,188,189],{"class":43,"line":57},[41,190,191],{},"{{ alert({ type: \"info\", title: \"提示\", content: \"这是一条信息。\" }) }}\n",[12,193,63],{},[12,195,196],{},"实际渲染效果：",[12,198,199],{},"{% from \"components\u002Falert.njk\" import alert %}",[12,201,202],{},[203,204],"binding",{"value":205},"alert({ type: \"info\", title: \"提示\", content: \"这是一条信息。\" })",[12,207,208],{},"标签组件同理：",[12,210,30],{},[32,212,214],{"className":34,"code":213,"language":36,"meta":37,"style":37},"{% from \"components\u002Ftag.njk\" import tag %}\n\n{{ tag({ text: \"Eleventy\", href: \"\u002Ftags\u002Feleventy\u002F\", color: \"default\" }) }}\n",[16,215,216,221,225],{"__ignoreMap":37},[41,217,218],{"class":43,"line":44},[41,219,220],{},"{% from \"components\u002Ftag.njk\" import tag %}\n",[41,222,223],{"class":43,"line":50},[41,224,54],{"emptyLinePlaceholder":53},[41,226,227],{"class":43,"line":57},[41,228,229],{},"{{ tag({ text: \"Eleventy\", href: \"\u002Ftags\u002Feleventy\u002F\", color: \"default\" }) }}\n",[12,231,63],{},[12,233,234],{},"{% from \"components\u002Ftag.njk\" import tag %}",[12,236,237],{},[203,238],{"value":239},"tag({ text: \"Eleventy\", href: \"\u002Ftags\u002Feleventy\u002F\", color: \"default\" })",[21,241,243],{"id":242},"五组件参数","五、组件参数",[12,245,246,247,251,252,255],{},"所有组件都以",[248,249,250],"strong",{},"字典","形式传参，可选的键取决于组件定义。以 ",[16,253,254],{},"button"," 为例：",[12,257,30],{},[32,259,261],{"className":34,"code":260,"language":36,"meta":37,"style":37},"{{ button({\n  text: \"提交\",\n  type: \"primary\",\n  size: \"lg\",\n  block: true,\n  disabled: false\n}) }}\n",[16,262,263,268,273,278,283,288,294],{"__ignoreMap":37},[41,264,265],{"class":43,"line":44},[41,266,267],{},"{{ button({\n",[41,269,270],{"class":43,"line":50},[41,271,272],{},"  text: \"提交\",\n",[41,274,275],{"class":43,"line":57},[41,276,277],{},"  type: \"primary\",\n",[41,279,280],{"class":43,"line":142},[41,281,282],{},"  size: \"lg\",\n",[41,284,285],{"class":43,"line":148},[41,286,287],{},"  block: true,\n",[41,289,291],{"class":43,"line":290},6,[41,292,293],{},"  disabled: false\n",[41,295,297],{"class":43,"line":296},7,[41,298,299],{},"}) }}\n",[12,301,63],{},[303,304,305,321],"table",{},[306,307,308],"thead",{},[309,310,311,315,318],"tr",{},[312,313,314],"th",{},"参数",[312,316,317],{},"类型",[312,319,320],{},"说明",[322,323,324,337,356,380,400,413],"tbody",{},[309,325,326,331,334],{},[327,328,329],"td",{},[16,330,161],{},[327,332,333],{},"string",[327,335,336],{},"按钮文字",[309,338,339,344,346],{},[327,340,341],{},[16,342,343],{},"href",[327,345,333],{},[327,347,348,349,352,353],{},"有值时渲染为 ",[16,350,351],{},"\u003Ca>","，否则为 ",[16,354,355],{},"\u003Cbutton>",[309,357,358,363,365],{},[327,359,360],{},[16,361,362],{},"type",[327,364,333],{},[327,366,367,370,371,370,374,370,377],{},[16,368,369],{},"primary"," \u002F ",[16,372,373],{},"secondary",[16,375,376],{},"success",[16,378,379],{},"danger",[309,381,382,387,389],{},[327,383,384],{},[16,385,386],{},"size",[327,388,333],{},[327,390,391,370,394,370,397],{},[16,392,393],{},"sm",[16,395,396],{},"md",[16,398,399],{},"lg",[309,401,402,407,410],{},[327,403,404],{},[16,405,406],{},"block",[327,408,409],{},"boolean",[327,411,412],{},"是否占满整行",[309,414,415,420,422],{},[327,416,417],{},[16,418,419],{},"disabled",[327,421,409],{},[327,423,424],{},"是否禁用",[21,426,428],{"id":427},"六注意事项","六、注意事项",[12,430,431,432,435,436,439],{},"（一）",[248,433,434],{},"组件需要显式导入","。Nunjucks 的 macro 不像 Vue 组件那样自动注册，必须在文章里用 ",[16,437,438],{},"from ... import ..."," 后再调用。",[12,441,442,443,446],{},"（二）",[248,444,445],{},"字典里不能嵌套双花括号","。以下写法是错的——字典内部不能再写模板表达式，需要先 set 再引用：",[12,448,30],{},[32,450,452],{"className":34,"code":451,"language":36,"meta":37,"style":37},"{% set href = \"\u002Ftags\u002F\" + (t | tagSlug) + \"\u002F\" %}\n{{ tag({ text: t, href: href }) }}\n",[16,453,454,459],{"__ignoreMap":37},[41,455,456],{"class":43,"line":44},[41,457,458],{},"{% set href = \"\u002Ftags\u002F\" + (t | tagSlug) + \"\u002F\" %}\n",[41,460,461],{"class":43,"line":50},[41,462,463],{},"{{ tag({ text: t, href: href }) }}\n",[12,465,63],{},[12,467,468,469,472,473,476,477,479,480,483],{},"（三）",[248,470,471],{},"Markdown 里的 shell 语法可能被误解析","。Nunjucks 会把花括号加井号当作注释开始标记，shell 脚本里取字符串长度的那种写法会触发 ",[16,474,475],{},"expected end of comment"," 错误。解决办法是用 ",[16,478,30],{}," 包裹那一行，或者改用等价的 shell 命令，例如 ",[16,481,482],{},"expr length \"$str\"","。",[12,485,486,487,490],{},"（四）",[248,488,489],{},"构建时编译","。正文中的 Nunjucks 在构建阶段执行，输出纯 HTML。若 macro 名或参数拼写错误，会在构建时报错，而不是静默忽略。",[12,492,493,494,497],{},"（五）",[248,495,496],{},"没有运行时状态","。本站是静态站点，正文里不存在 Vue 那样的响应式状态。需要交互（比如切换显示）时，要借助 jQuery 或原生 JS，且只在现代浏览器中执行，IE7 只保证静态内容的可读性。",[12,499,500,501,504,505,508,509,483],{},"（六）",[248,502,503],{},"不要写 style 块","。文章内的样式用已有 CSS 类或内联 ",[16,506,507],{},"style"," 属性，不推荐在 Markdown 里写 ",[16,510,511],{},"\u003Cstyle>",[21,513,515],{"id":514},"七小结","七、小结",[12,517,518],{},"Markdown 与 Nunjucks 的融合让静态内容具备了组件化能力。文章可以引用全局数据、复用 UI 组件、按条件或循环渲染结构化内容，同时保持构建产物是纯静态 HTML，兼容到 IE7。这使得一批需要在多篇文章里重复出现的结构，可以被抽成组件统一维护。",[507,520,521],{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":37,"searchDepth":50,"depth":50,"links":523},[524,525,526,527,528,529,530],{"id":23,"depth":50,"text":24},{"id":69,"depth":50,"text":70},{"id":113,"depth":50,"text":114},{"id":166,"depth":50,"text":167},{"id":242,"depth":50,"text":243},{"id":427,"depth":50,"text":428},{"id":514,"depth":50,"text":515},"2026-10-03","本站 Markdown 文件由 Nunjucks 编译，正文中可直接调用组件 macro、条件渲染与循环。",{},"\u002Fmarkdown-nunjucks-usage-2026-09-18",{"title":6,"description":532},"markdown-nunjucks-usage-2026-09-18",[538,539,540],"Nunjucks","Markdown","Eleventy","MdUbcFEW1qf-NzpeyZmkI2XJI4m6X-6wIMK7c9vGCSs",1794733995730]