hugo对md文件统一管理的常见方案之一是在archetype文件夹内添加模板样式,然后每次通过cmd/powershell的hugo new指令生成对应模版样式。但如此每次都要求输入:
hugo new --kind archetype-01 01file/01text.md
生成的md文件继承archetype中模版的格式。
但我希望实现:将notion中的md文件一键分类入对应文件夹后,不必再使用终端新建,只通过IDE在对应文件夹内新建md文件就可以自动继承父模版,不必在单个博客md文件内生成多余的front matter内容。我的需求是主分类文件夹下包含子文件夹分类,子文件夹有固定tag,避免手动添加或多次键入date和title。
第一步 通过powershell的脚本完成一键分类
特殊要求是显式指定UTF-8编码处理避免生成乱码:
$basePath = ".\content\03archetype"
# 中文标签 -> 英文子文件夹映射
$tagMap = @{
"book" = "01"
"movie" = "02"
}
Get-ChildItem $basePath -Filter *.md | ForEach-Object {
# 只读取前4行并指定编码 UTF8
$lines = Get-Content $_.FullName -TotalCount 4 -Encoding UTF8
$bodyLines = Get-Content $_.FullName -Encoding UTF8 | Select-Object -Skip 4
$title = ""
$tag = ""
$date = $null # 用 null 来表示没有找到日期
foreach ($line in $lines) {
if ($line -match '^#\s*(.+)$') {
$title = $matches[1]
} elseif ($line -match '^Tags:\s*(.+)$') {
$tag = $matches[1]
} elseif ($line -match '^date:\s*(.+)$') {
try {
$dateObj = Get-Date $matches[1]
$date = $dateObj.ToString("yyyy-MM-dd")
} catch {
$date = (Get-Date).ToString("yyyy-MM-dd")
}
}
}
if ($title -eq "") { return }
# 如果没有在 Front Matter 中找到日期,跳过日期的修改
if ($date -eq $null) {
# 如果没有 `date` 字段,则不修改日期,保持原样
$date = "" # 可以选择空字符串或其他标识,表示不修改 `date`
}
$newHeader = @(
'---'
"title: `"$title`""
"tags: [`"$tag`"]"
"date: $date"
"draft: false"
'---'
''
)
$newContent = $newHeader + $bodyLines
# 写回文件时显式 UTF-8 编码
Set-Content $_.FullName $newContent -Encoding UTF8
# 根据 Tags 移动文件到英文子文件夹
if ($tagMap.ContainsKey($tag)) {
$targetDir = Join-Path $basePath $tagMap[$tag]
if (!(Test-Path $targetDir)) {
New-Item -ItemType Directory -Path $targetDir | Out-Null
}
Move-Item $_.FullName (Join-Path $targetDir $_.Name)
}
}
同时可以顺便用脚本将分好类后的多余文本删除/重命名文件标题。
第二步 在每个文件夹下新建_index.md
Hugo的生成逻辑里,文件夹只有在有_index.md的文件时,才可以解析显示页面,不报错。页面md文件的内容是front matter,根据个性化需求填写。例如:
\content\05architect\_index.md
---
title: "Ⅴ测试篇"
navtitle: "测试篇 ▪ 信息留档"
draft: false
---
\content\05architect\05_01\_index.md
---
title: "小岛建设"
cascade:
tags: ["小岛建设"]
draft: false
---
其中cascade下的内容就是关键的继承部分,完成这个配置后,新建博文md文件就不必再手动填写tags等内容了,只需要在对应tag文件夹下新建md,键入文本,即可生成博文内容。
第三步 避免重复键入日期与title
因为不愿在md里键入额外的frontmatter,所以每次新建md文件会将时间添加入文件名,一来是键入直接快速,二来也方便排序管理,hugo很贴心地提供了文件名下对应格式的日期识别功能,具体实现只用在配置toml中写入:
[frontmatter]
date = [":filename",":default" ]
新建md时日期格式以"YYYY-MM-DD"格式输入即可识别。
而title部分研究发现toml内不支持动态读取(也可能是我没有调试成功),所以我采用了很呆的方法:为了文件管理便捷性放弃配置title。转而在需求显示标题的layouts中用go template进行文件名节选,实现网页浏览可读性。
{{ if .Title }}
{{ .Title }}
{{ else }}
{{ $filename := .File.ContentBaseName }}
{{ $title := replaceRE `^\d{4}-\d{2}-\d{2}_` "" $filename }}
{{ $title | replaceRE "-" " " | title }}
{{ end }}
例如本篇博文的文件标题为:<2026-04-14_02_hugo MD文件收纳方案.md>,经过处理后在前端显示为<02_hugo MD文件收纳方案>。