昨天的文章中写到了因为 “:“和”=“的问题,导致固定链接不生效。后面提到“没有思考出如何自增ID号码的方法”作为文章ID。最后的设置结果是使用日期+文章标题作为固定连接。但我这个短域名后面拖着一串长长的文章名的URL在视觉上着实有点难受。

今天,经过与deepseek的深度探讨,整理一个自增ID的方法来作为文章ID。

整体的思路,在文章.md的头部信息,也就是Front Matter中,添加一个名为post_id的变量,第一篇文章为1,第二篇文章为2,依次类推,如果中途有删除文章,则那个id就废除不用了。

实现方法,因为我使用的windows+vscode维护hugo博客,因此使用powershell脚本,先遍历content/posts目录下的所有.md文件,取出所有.md文件中post_id的最大值,将post_id最大值加1,然后创建新文章.md,将加1后的post_id写入新文章,因为在config.yml中无法将自定义变量作为固定链接的取值函数参数,因此同部将post_id的值写入到slug ““中,在config.yml中将slug作为固定链接参数。

这样每次创建新文章只要在根目录运行个ps1脚本就可以了,不用再写文章路径和文件名等内容了。

以下是powershell脚本:

# 强制设置控制台编码为 UTF-8
$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding

# 定义路径和参数
$postsRoot = "content\posts"  # 文章根目录
$archetype = "posts"          # Archetype名称
$newPostDir = "content\posts\blog"  # 新文章存放目录(可选,按需修改)

# 1. 递归查找所有文章并提取最大 post_id
$maxId = 0
Get-ChildItem -Path $postsRoot -Filter *.md -Recurse | ForEach-Object {
    $content = Get-Content $_.FullName -Raw
    if ($content -match "post_id:\s*(\d+)") {
        $currentId = [int]$matches[1]
        if ($currentId -gt $maxId) {
            $maxId = $currentId
        }
    }
}

# 2. 生成新 ID
$newId = $maxId + 1

# 3. 创建新文章(自动生成文件名)
$newPostName = "post-$newId.md"
hugo new "$newPostDir\$newPostName" --kind $archetype  # 新文章路径可自定义

# 4. 替换新文章的 post_id
$newPostPath = "$newPostDir\$newPostName"
(Get-Content $newPostPath -Raw -Encoding UTF8) -replace 'post_id: 0', "post_id: $newId" `
                                              -replace 'slug: ""', "slug: `"$newId`"" |  # 关键修改
  Set-Content $newPostPath -Encoding UTF8

Write-Host "✅ 新文章已创建 | ID: $newId | 路径: $newPostPath"

ps:因为遇到的编码问题导致Front Matter的中文乱码,困扰了好久,着重让deepseek强调了UTF-8编码的问题。

文章链接的问题已经解决好了,那页面怎么办?页面没有post_id,那就使用title呗。这样我们将默认链接设置为title,一是让页面有一个固定连接,二可以给忘记设置post_id和slug的文章兜个底。

以下为主题的config.yml中的代码:

uglyURLs: true # 本项为true时URL结尾.html,false或没有时,无.html字样,以/结尾
permalinks: # 访问博客时网址的显示形式
    default: /:title
    posts: /:slug

完工!

再次ps:还想以纯post_id的数字结尾假装一下动态博客的,链接结尾的”/“需要服务器端进行URL的重写设置,为了不同托管平台可用的一致性,算了,还是加上.html吧