
本文详解如何在 Hugo HTML 短代码中安全传递、保留换行与列表结构的用户输入 Markdown 内容,并通过 markdownify 或 renderString 函数实现原生 Markdown 渲染,避免内容被扁平化为单行纯文本。
本文详解如何在 hugo html 短代码中安全传递、保留换行与列表结构的用户输入 markdown 内容,并通过 markdownify 或 renderstring 函数实现原生 markdown 渲染,避免内容被扁平化为单行纯文本。
在 Hugo 中使用短代码(shortcode)时,若需将用户提供的富格式内容(如含换行、列表、加粗等的 Markdown 生物简介)注入 HTML 模板并真实渲染为 HTML,而非作为纯字符串输出,关键在于两点:正确声明多行变量 + 显式触发 Markdown 解析。
✅ 正确声明多行 Markdown 变量(Front Matter 或 shortcode 参数)
Hugo 支持 YAML 风格的多行字符串语法。请避免用反引号包裹(如 "line1\n- item"),而应使用管道符 | 语法,确保换行与缩进被完整保留:
--- name: "Alice Chen" title: "Senior Researcher" img: "/images/alice.jpg" bio: |- Here are some achievements: - First thing - List item - and this is **really** important ---
⚠️ 注意:
|-表示“去除末尾换行”,更符合内容语义;若需保留末尾空行,可用|。缩进需保持一致(推荐 2 空格),否则 YAML 解析可能失败。
✅ 在 HTML 短代码中渲染 Markdown 内容
原始短代码中 {{ .Get "bio" }} 仅做字符串插值,不解析 Markdown。需改用内置函数:
将选定的 Obsidian 笔记发布为静态站点并部署到 Cloudflare Pages。
<table>
<tr>
<td valign="top" rowspan="2" width="170">
<img src="{{ .Get "img" }}" style="max-width:90%" alt="{{ .Get "name" }}">
</td>
<td width="600" height="30">
<b>{{ .Get "name" }}</b>, <i>{{ .Get "title" }}</i>
</td>
</tr>
<tr>
<td valign="top">
{{ .Get "bio" | markdownify }}
</td>
</tr>
</table>
<br>✅ markdownify 是最简方案:它将传入字符串作为 Markdown 解析,输出标准 HTML(支持标题、段落、列表、强调等),并自动转义 XSS 风险字符,安全可靠。
? 进阶:需要自定义渲染(如添加 class、处理内联链接)?
使用 renderString(Hugo ≥ 0.115)可获得更高控制力,尤其适合需复用页面级渲染逻辑(如 layouts/_default/_markup/render-image.html)的场景:
{{ .Get "bio" | renderString "markdown" }}该函数会调用 Hugo 的完整 Markdown 渲染流水线,支持自定义渲染器配置(如启用 emoji、footnotes),但对简单场景 markdownify 已完全足够。
? 关键总结
- ❌ 错误做法:用双引号包裹多行内容 → 换行丢失,Markdown 符号(
-,**)原样输出; - ✅ 正确做法:YAML 中用
|或|-声明多行字符串; - ✅ 必须步骤:在 shortcode 模板中对
.Get "bio"显式调用| markdownify; - ✅ 安全保障:
markdownify默认启用 HTML 转义,无需额外防护; - ? 无需新建
.md短代码文件——HTML 短代码(.html)完全支持管道函数,{{% %}}仅用于避免内部模板解析的包裹型 shortcode,此处不适用。
通过以上调整,你的生物简介将真正以结构化 HTML 呈现:段落分隔清晰、列表层级准确、加粗文字高亮显示——既保持作者意图,又兼顾安全与性能。

















