Hugo `hugo list published` 命令详解:一行命令列出站点全部已发布内容
Hugohugo list published命令详解一行命令列出站点全部已发布内容【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugohugo list published是 Hugo 静态站点生成器list命令族中的成员用于以 CSV 格式输出站点中所有已发布内容的清单——即既不是草稿draft、也没有未来发布日期future、更未过期expired的页面。在内容审核、CI 发布检查、SEO 巡检、与外部 CMS 或脚本对接等场景下它都能快速给出机器可读的内容全貌。读完本文你将掌握该命令的过滤规则、CSV 输出格式、全部可用参数以及它与hugo list drafts / future / expired / all等兄弟命令的差异并能结合源码理解其只收集、不渲染的实现原理。命令概述什么是hugo list publishedhugo list published是 Hugo 内置的 hugo list 子命令之一官方对其的定义是List content that is not draft, future, or expired. 列出既非草稿、也非未来、更非过期的内容。即它的职责非常纯粹把当前站点中真正已发布的页面逐行打印出来。该命令默认不会对任何页面执行 HTML 渲染因此执行速度很快非常适合作为数据管道或自动化脚本中的内容审计入口。快速上手在站点根目录即包含hugo.toml/hugo.yaml/hugo.json的位置执行hugo list published输出会以 CSV 表格形式直接打印到标准输出stdout例如path,slug,title,date,expiryDate,publishDate,draft,permalink,kind,section content/blog/hello.md,hello,Hello Hugo,2024-01-15T10:00:00Z,0001-01-01T00:00:00Z,2024-01-15T10:00:00Z,false,https://example.org/blog/hello/,page,blog首行是固定的表头之后每一行对应一个已发布页面。CSV 字段使用逗号分隔字段内部不会出现逗号换行可直接被 Excel、Pythoncsv模块或awk等工具解析。过滤逻辑Hugo 眼中的已发布到底是什么hugo list published之所以与hugo list all不同关键在于它的包含include判定条件。从源码看commands/list.go 中published子命令的过滤函数为shouldInclude : func(p page.Page) bool { return !p.Draft() !resource.IsFuture(p) !resource.IsExpired(p) p.File() ! nil }一个页面要进入已发布清单必须同时满足以下四个条件条件含义判断依据!p.Draft()页面未被标记为草稿前置元数据中的draft字段!resource.IsFuture(p)发布日期未到publishDate不在当前时间之后!resource.IsExpired(p)未超过过期时间expiryDate不在当前时间之前p.File() ! nil页面来自真实内容文件排除纯内存 / 虚拟页面等无文件来源的页面日期判定的源码级实现IsFuture与IsExpired定义在 resources/resource/dates.go// IsFuture returns whether the argument represents the future. func IsFuture(d Dated) bool { if d.PublishDate().IsZero() { return false } return d.PublishDate().After(htime.Now()) } // IsExpired returns whether the argument is expired. func IsExpired(d Dated) bool { if d.ExpiryDate().IsZero() { return false } return d.ExpiryDate().Before(htime.Now()) }值得注意的两个边界行为未设置publishDate零值时间时IsFuture直接返回false即不会被视为未来内容未设置expiryDate零值时间时IsExpired直接返回false即永远不会过期判定使用的当前时间来自htime.Now()而非time.Now()。htime是 Hugo 的可注入时钟因此你可以通过继承参数--clock人为指定当前时间从而模拟未来或过去的时间点来验证发布状态详见下文参数章节。四个前置时间字段页面是否已发布本质上取决于内容前置元数据front matter中的四个日期字段。相关字段及别名定义见 docs/content/en/configuration/front-matter.md 与 docs/content/en/content-management/front-matter.md字段别名对list published的影响draft—为true时页面永远不计入已发布publishDatepubdate,published晚于当前时间则视为未来内容expiryDateunpublishdate早于当前时间则视为过期内容date—不直接影响过滤但会出现在 CSV 输出的date列中这也与 Hugo 的常规构建行为保持一致根据 docs/content/en/getting-started/usage.md默认情况下 Hugo 不会发布草稿、publishDate在未来的内容以及expiryDate在过去的内容。也就是说hugo list published的过滤规则与 Hugo 默认构建时哪些页面会被发布的规则是对齐的。CSV 输出格式详解每一列代表什么list家族的 CSV 表头与记录生成逻辑统一定义在 commands/list.go 的createRecord函数与 commands/list.go 的表头写入处writer.Write([]string{ path, slug, title, date, expiryDate, publishDate, draft, permalink, kind, section, })各列含义如下列名说明取值示例path内容文件相对于站点工作目录的路径使用/分隔符content/blog/hello.mdslug页面 slugURL 段hellotitle页面标题Hello Hugodate页面日期RFC3339 格式2024-01-15T10:00:00ZexpiryDate过期时间RFC3339 格式未设置时为 Go 零值时间0001-01-01T00:00:00ZpublishDate发布日期RFC3339 格式2024-01-15T10:00:00Zdraft是否为草稿布尔值falsepermalink页面最终 URL由baseURL与路径共同决定https://example.org/blog/hello/kind页面类型如page、home、section、taxonomy等pagesection页面所属的 section栏目blog日期统一使用time.RFC3339格式输出未设置expiryDate或publishDate时输出 Go 时间零值0001-01-01T00:00:00Z这也再次印证了上方IsFuture/IsExpired中对零值时间的特殊处理。path列会去掉工作目录前缀并统一为/分隔符保证跨平台Windows / Linux / macOS输出一致。由于hugo list published只打印这些结构化字段而不渲染页面你可以将它的输出重定向到文件例如hugo list published published.csv再交由脚本或 BI 工具做进一步分析。参数参考子命令选项与继承选项hugo list published本身仅有一个选项-h, --help help for published与list家族的其他子命令一样它还会继承来自父命令hugo根命令的全部选项--clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.0009:00 --config string config file (default is hugo.yaml|json|toml) --configDir string config dir (default config) -d, --destination string filesystem path to write files to -e, --environment string build environment --ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern --logLevel string log level (debug|info|warn|error) --noBuildLock dont create .hugo_build.lock file --quiet build in quiet mode -M, --renderToMemory render to memory (mostly useful when running the server) -s, --source string filesystem path to read files relative from --themesDir string filesystem path to themes directory其中与list published关系最密切的是--clock注入一个虚拟的当前时间。因为发布 / 过期判定都基于htime.Now()利用它可以在不修改任何内容文件的前提下模拟未来某个时刻或过去的某个时刻来看哪些内容会成为已发布状态。例如# 把当前时间拨到 2021-11-06观察届时哪些页面已发布 hugo list published --clock 2021-11-06T22:30:00.0009:00-s, --source指定站点根目录。当你在其他目录下执行命令时用它指向 Hugo 项目位置。-e, --environment选择构建环境如development/production环境不同可能加载不同的配置片段。--config/--configDir指定配置文件或配置目录默认依次查找hugo.yaml、hugo.json、hugo.toml见参数默认值。--quiet抑制额外日志只输出干净的 CSV 数据适合管道处理。完整用法示例# 基本用法列出全部已发布内容 hugo list published # 从其他目录指向站点并输出到文件 hugo list published -s /path/to/my-site published.csv # 模拟特定时刻下的已发布清单用于排期核对 hugo list published --clock 2025-12-31T23:59:59Z与hugo list家族其他子命令的对比hugo list本身不能单独使用必须配合子命令其提示信息为 List requires a subcommand, e.g. hugo list drafts。全部五个子命令的过滤逻辑都在 commands/list.go 中定义对比如下子命令功能过滤条件源码备注hugo list drafts列出草稿p.Draft() p.File() ! nil强制buildDrafts、buildFuture、buildExpiredhugo list future列出未来内容IsFuture(p) p.File() ! nil强制buildFuture、buildDraftshugo list expired列出过期内容IsExpired(p) p.File() ! nil强制buildExpired、buildDraftshugo list all列出全部内容p.File() ! nil含草稿、未来、过期三者全部强制开启hugo list published列出已发布内容!p.Draft() !IsFuture(p) !IsExpired(p) p.File() ! nil不额外开启任何 build 开关可以看到drafts、future、expired子命令会通过cfg.Set(...)显式打开对应的构建开关buildDrafts、buildFuture、buildExpired以便让被过滤掉的页面也能进入 Hugo 的页面集合而published只调用list(cd, r, shouldInclude)不设置任何开关——因为它要筛选的正是默认构建开关下会被发布的那部分页面。五个子命令共用同一个list函数与同一个 CSV 输出格式因此列结构完全一致便于横向比较例如分别执行hugo list drafts与hugo list published即可快速盘点草稿积压情况与线上内容清单。底层实现原理只收集、不渲染hugo list published的速度优势来自其构建方式。在 commands/list.go 的list函数中bcfg : hugolib.BuildCfg{SkipRender: true}SkipRender: true表示 Hugo 只执行内容收集、页面对象构建与日期逻辑处理跳过模板渲染与静态文件输出。随后通过h.Pages()见 hugolib/hugo_sites.go获取全站页面集合逐页套用shouldInclude过滤函数命中者即用csv.Writer写出一行记录。整体数据流为读取配置flagsToCfg合并命令行参数r.Build(...)以SkipRender模式构建站点产出全站页面集合对每个页面执行shouldInclude判定published即非草稿、非未来、非过期、有文件命中页面经createRecord转为 10 列 CSV 记录写入r.StdOut。由于不涉及模板执行该命令在大型站点上也能快速返回结果适合在 CI 流水线中作为发布前置检查或内容统计工具。测试验证官方如何验证该命令的行为仓库中的测试脚本 testscripts/commands/list.txt 完整覆盖了list家族的行为。它构建了一个包含draft.md草稿、expired.md2019 年过期、future.md2090 年发布、draftfuture.md草稿 未来、draftexpired.md草稿 过期的测试站点并断言hugo list drafts只输出draft.md、draftexpired.md、draftfuture.mdhugo list future输出future.md与draftfuture.md但不输出expired.mdhugo list expired输出expired.md与draftexpired.md但不输出future.mdhugo list all输出全部五个页面对hugo list expired传入--clock 2000-01-01T00:00:00Z后expired.md不再出现在结果中——因为把当前时间拨回 2000 年后expiryDate: 2019-01-01不再早于当前时间页面便不再过期。最后一个用例直观地演示了--clock对日期判定的影响也再次印证了IsExpired基于htime.Now()的实现。如果你需要在自己的项目中复现可以参考该测试文件的站点结构在内容文件的 front matter 中组合设置draft、date、publishDate、expiryDate四个字段。小结hugo list published是 Hugo 内容审计工具箱中一个简单而实用的成员它用非草稿、非未来、非过期、有文件来源四个条件精确定义已发布以统一的 10 列 CSV 格式输出结构化结果并借助SkipRender实现轻量快速的内容盘点。结合--clock参数你还能在任意时间维度上推演站点内容状态为发布排期、CI 检查和内容治理提供可靠的数据支撑。【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考