Hugo如何实现自动在首个段落分隔处截断内容摘要
问题说明
将博客从Jekyll迁移至Hugo时,需要保留原有摘要生成逻辑:自动在第一个段落分隔(空行)位置结束摘要截取,预期截取效果如下:
I should be included in the content summary. Still in summary. This is no longer part of summary
Hugo原生的自动摘要拆分仅支持按固定长度截断,需要实现首个段落分隔处截断摘要的可行方案。
实现方案
方案1:模板层自定义截断逻辑(推荐,无内容侵入)
不需要修改已有文章内容,直接替换列表页、摘要位的原生.Summary调用逻辑即可,核心思路是直接读取文章原始内容,按连续两个换行(段落分隔符)拆分后取第一段作为摘要。
基础实现代码:
{{/* 取第一个空行前的内容作为摘要 */}} {{ $summaryPart := index (split .RawContent "\n\n") 0 }} {{ $summaryPart | markdownify }}
如果需要兼容手动摘要优先级(优先读取front matter自定义摘要、其次识别<!--more-->手动标记、最后自动取首段),可以用完整判断逻辑:
{{/* 优先使用front matter中手动填写的摘要 */}} {{ if .Params.summary }} {{ .Params.summary | markdownify }} {{/* 其次使用<!--more-->标记手动分割的摘要 */}} {{ else if .Truncated }} {{ .Summary }} {{/* 都没有时自动取第一个段落作为摘要 */}} {{ else }} {{ $firstPara := index (split .RawContent "\n\n") 0 }} {{ $firstPara | markdownify }} {{ end }}
如果你的内容文件使用Windows风格的\r\n换行,把拆分用的分隔符从\n\n替换为\r\n\r\n即可,也可以先做换行符统一处理再拆分,避免匹配失效。
方案2:构建前批量注入摘要分隔标记
如果不想修改模板逻辑,可以写一个简单的预处理脚本,在Hugo构建前遍历所有文章文件,对没有手动设置摘要、也没有加<!--more-->标记的文章,自动在第一个空行位置插入Hugo识别的摘要分隔标记,插入后Hugo原生的摘要逻辑就会自动按首段截断,和预期效果完全一致。
简单的Python处理脚本示例:
import os import re CONTENT_PATH = "./content/" SUMMARY_MARK = "<!--more-->" # 遍历content目录下所有markdown文件 for root, _, files in os.walk(CONTENT_PATH): for filename in files: if not filename.endswith(".md"): continue file_full_path = os.path.join(root, filename) with open(file_full_path, "r", encoding="utf-8") as f: file_content = f.read() # 跳过已经配置了手动摘要、已经加了分隔标记的文件 front_matter = file_content.split("---")[1] if file_content.startswith("---") else "" if SUMMARY_MARK in file_content or "summary:" in front_matter: continue # 在第一个段落分隔位置插入摘要标记 processed_content = re.sub(r"\n\n", f"\n\n{SUMMARY_MARK}\n\n", file_content, count=1) with open(file_full_path, "w", encoding="utf-8") as f: f.write(processed_content)
每次写新文章后跑一次脚本,或者把脚本加到构建命令的前置步骤里就行,不需要额外改Hugo配置。
注意事项
- 如果文章开头存在短代码、头图、前言提示等非正文段落内容,可以在拆分逻辑里加对应规则,跳过开头的非正文元素后再找第一个正文段落的分隔点。
- 两种方案都可以按需调整截断规则,比如需要取前两个段落作为摘要,只要把
split后取索引0改成取前2个元素拼接即可。
内容的提问来源于stack exchange,提问作者farlee2121
相关产品推荐
相关产品推荐

