Hugo Permalink 令牌全解:从配置到源码的 URL 模式定制指南
Hugo Permalink 令牌全解从配置到源码的 URL 模式定制指南【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo本文以 Hugo 文档站中共享的 permalink 令牌文档docs/content/en/_common/permalink-tokens.md为主体完整梳理permalinks配置中所有可用令牌的含义、版本演进与切片语法并结合 resources/page/permalinks.go 的实现与 resources/page/permalinks_test.go 的测试用例讲清每个令牌底层如何展开为 URL。读完后你能够独立完成按日期、按栏目层级、按内容基名等维度的 URL 定制并能看懂 Hugo 校验与展开 permalink 模式的完整机制。令牌的使用场景permalink 令牌用于定义页面 URL 模式仓库中主要有两处入口站点级permalinks配置见 docs/content/en/configuration/permalinks.md支持 map 形式与 0.161.0 引入的数组形式可精确到页面类型kind、路径与语言维度。Front matterurl字段见 docs/content/en/content-management/urls.md 的 “Tokens” 一节允许在url常配合cascade使用中直接使用同一套令牌例如# content/foo/bar/_index.md title Bar [[cascade]] url /:sections[last]/:slug需要注意的是front matter 中的url会覆盖任何与之匹配的 permalink 模式permalinks 文档中有明确 NOTE 说明。以下逐类完整展开原文档定义的全部令牌。日期类令牌以下 7 个令牌均取自内容 front matter 的date字段令牌含义:year4 位年份:month2 位月份:monthname月份英文名称如April:day2 位日期:weekday1 位星期数字Sunday 0与 Gotime.Weekday一致:weekdayname星期英文名称如Friday:yearday1–3 位的“一年中的第几天”YearDay以date 2012-04-06 03:01:59为例测试数据 给出的展开结果是/:year/:yearday/:month/:monthname/:day/:weekday/:weekdayname/ → /2012/97/04/April/06/5/Friday/实现位于 pageToPermalinkDate:year直接取Date().Year():month/:day用%02d强制补零:weekday是int(Weekday())所以是 0–6 而非 1–7:yearday取YearDay()。栏目与标题类令牌:section与:sectionslug:section内容所属的栏目名。实现为直接返回 p.Section()。:sectionslugHugo 0.149.0 新增。取所属栏目的 slug 化名称——优先 front matter 的slug否则title再否则自动生成的标题。实现见 pageToPermalinkSectionSlug它作用于FirstSection()且对首页home返回空字符串。:sections与:sectionslugs支持切片语法:sections内容的完整栏目层级路径如/a/b/c展开为/a/b/c/。:sectionslugsHugo 0.149.0 新增。与:sections相同但每一层使用栏目的 slug 化名称测试中a-slug/b-slug/c-slug层级展开为/a-slug/b-slug/c-slug/见 permalinks_test.go#L70-L105。两者都支持slice syntax切片语法选取层级子集写法含义:sections[1:]除第一个外的所有层级:sections[:last]除最后一个外的所有层级:sections[last]仅最后一个层级:sections[1:2]第 2、3 个层级0 基索引:sections[0]仅第一个层级切片是“宽容”的越界不会 panic。从源码 toSliceFunc 可以看到它把n len(ss)的下界钳制为-1、上界钳制为len(ss)格式非法如[1:}时返回 nil。对应测试 TestPermalinkExpansionSliceSyntax 覆盖了越界、负数、空输入等边界[1:5]、[-1:5]都安全回退[5:]返回空。:title与:slug:titlefront matter 的title否则自动标题。Hugo 会为没有实体文件支撑的 section、taxonomy、term 页自动生成标题。:slug优先取slug否则title再否则自动标题。一个容易踩坑的细节实现 pageToPermalinkTitle 中有一个segmentReplacer会把标题中的/和\替换为-防止标题里的斜杠意外引入额外的路径段对应 issue #3577测试见 TestPermalinkExpansionTitleSlash。但 term 页分类术语页是例外——其标题中的/被保留用于构建多级分类层级issue #5571。显式slug则原样使用不做该替换。文件名类令牌与版本演进令牌状态说明:filenamev0.144.0 起弃用改用:contentbasename:slugorfilenamev0.144.0 起弃用改用:slugorcontentbasename:contentbasenamev0.144.0 新增内容基名content base name即去掉扩展名等标识符后的文件名保留原始大小写:slugorcontentbasenamev0.144.0 新增有slug用slug否则用内容基名:filename的历史实现 pageToPermalinkFilename 有特殊的 bundle 处理文件名是indexleaf bundle时回退为目录名是_index时返回空。新的:contentbasename则直接取 PathInfo().Unnormalized().BaseNameNoIdentifier()由路径解析器 common/paths/pathparser.go 中的BaseNameNoIdentifier()计算——“Unnormalized” 意味着保留原始大小写而内容路径解析时另有归一化副本全小写、空格转连字符。测试数据中的对照permalinks_test.go#L52-L59文件/test-page/index.md、无 slug 时:slugorcontentbasename展开为/test-page/设置slug myslug后展开为/myslug/。补充Go time 布局字符串除上述命名令牌外Go 标准库time包的布局字符串组件也可直接作为令牌。官方文档给出的示例permalinks: posts: /:06/:1/:2/:title/展开后得到/12/4/6/...形式的年月日。机制见 callback 末尾的兜底判断Hugo 用一个固定的参考时间referenceTimeL70-L732019-11-09各字段互不相同且都不同于布局写法本身做referenceTime.Format(attr) ! attr检测——若格式化结果与布局串本身不同就认定这是一个合法的 Go 时间布局交给 pageToPermalinkDate 的p.Date().Format(dateField)处理。例如/:2006_01_02_15_04_05.000可展开为/2012_04_06_03_01_59.000permalinks_test.go#L45。源码视角模式如何被校验与展开令牌识别的正则所有令牌由 attributeRegexp:\w(\[.?\])?匹配——冒号后跟单词字符可选地跟一段[...]切片表达式。这也解释了:TITLE非法测试 注明“case is not normalized”令牌区分大小写:fred这类未知令牌直接报错permalink attribute not recognisedL272:year//:title这类连续斜杠也不合法permalinks_test.go#L108。识别优先级callback 的判定顺序是已知命名令牌knownPermalinkAttributes→sections[...]前缀 →sectionslugs[...]前缀 → Go time 布局兜底 → 报错。命名令牌表与本文前文的令牌清单一一对应共 15 个year、month、monthname、day、weekday、weekdayname、yearday、section、sectionslug、sections、sectionslugs、title、slug、slugorfilename、filename、contentbasename、slugorcontentbasename。模式缓存与展开NewPermalinkExpander在初始化阶段就会校验并预编译 所有配置模式含 target 的 glob 编译配置错误在启动期即暴露getOrParsePattern 通过patternCache按模式串缓存编译结果展开时逐令牌调用回调并做一次性strings.Replace。冒号转义若模式本身需要包含字面:可用\:转义。normalizeEscapeSequencesIn 先把\:替换为内部占位符\x00避免被误认为令牌展开结束后再还原。测试用例模式/special\::slug/对 slug 为The Slug的页面展开为/special:the-slug/permalinks_test.go#L189-L190 与 L213-L216。规则匹配顺序PermalinksConfig是有序切片Expand 按配置顺序逐条用 PageMatcher支持path、kind、lang、sites、environment等维度见 resources/page/page_matcher.go匹配第一条命中的规则生效。permalink 仅对page、home、section、taxonomy、term五类页面类型生效permalinksKindsSupport其他 kind 直接返回空。配置形式map 形式与数组形式令牌最终写在站点配置里DecodePermalinksConfig 同时支持两种形式。Map 形式按 kind 分组[permalinks.page] articles /blog/:year/:month/:slug/ [permalinks.section] articles /blog/顶层 key 是 kindpage、section等子 key 是栏目路径value 是令牌模式。map 形式的简单key pattern写法会自动为 page 和 term 两类各生成一条规则。按语言配置时把permalinks嵌套在语言 key 下[languages] [languages.de] label Deutsch [languages.de.permalinks] [languages.de.permalinks.page] articles /artikel/:year/:month/:slug/ [languages.de.permalinks.section] articles /artikel/ [languages.en] label English [languages.en.permalinks] [languages.en.permalinks.page] articles /blog/:year/:month/:slug/ [languages.en.permalinks.section] articles /blog/数组形式Hugo 0.161.0 起数组形式的每条规则必须有pattern可选targetpage matcher不写target即匹配所有页面。适合为“同一栏目的列表页与内容页分别定制、再按语言区分”这类精细场景[[permalinks]] pattern /artikel/ [permalinks.target] path {/articles} [permalinks.target.sites] [permalinks.target.sites.matrix] languages [de] [[permalinks]] pattern /artikel/:year/:month/:slug/ [permalinks.target] path {/articles/**} [permalinks.target.sites] [permalinks.target.sites.matrix] languages [de] [[permalinks]] pattern /blog/ [permalinks.target] path {/articles} [permalinks.target.sites] [permalinks.target.sites.matrix] languages [en] [[permalinks]] pattern /blog/:year/:month/:slug/ [permalinks.target] path {/articles/**} [permalinks.target.sites] [permalinks.target.sites.matrix] languages [en]需要“兜底”时把一个不带target的 pattern 放在数组末尾即可[[permalinks]] pattern /:section/:slug/小结日期令牌 7 个:year/:month/:monthname/:day/:weekday/:weekdayname/:yearday全部来自 front matterdate:weekday以 0 代表 Sunday。层级令牌:sections/:sectionslugs后者 0.149.0 起支持宽容的切片语法:sectionslug0.149.0取首个栏目的 slug 化名。文件名令牌在 0.144.0 完成换代:filename、:slugorfilename弃用:contentbasename、:slugorcontentbasename取代。任意 Gotime布局组件如:06、:1、:2可作为自定义日期令牌由参考时间格式化检测来识别。实现集中于 resources/page/permalinks.go行为回归由 resources/page/permalinks_test.go 覆盖含转义、越界切片、标题中斜杠、并发安全等用例页面侧的Permalink()/RelPermalink()接口定义在 hugolib/permalinker.go。【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Scrapy SEP-001:Item 字段填充 API 的设计之争——ItemForm 与 ItemBuilder 对比及其对 Item Loader 的深远影响

Scrapy SEP-001:Item 字段填充 API 的设计之争——ItemForm 与 ItemBuilder 对比及其对 Item Loader 的深远影响

Scrapy SEP-001:Item 字段填充 API 的设计之争——ItemForm 与 ItemBuilder 对比及其对 Item Loader 的深远影响 【免费下载链接】scrapy Scrapy, a fast high-level web crawling & scraping framework for Python. 项目地址: https://gitcode.com/GitHub_Tr…

2026/11/9 6:51:58 阅读更多 →
微信聊天记录导出成三种格式加一份年报:WeChatMsg 让备份留在本机

微信聊天记录导出成三种格式加一份年报:WeChatMsg 让备份留在本机

微信聊天记录导出成三种格式加一份年报:WeChatMsg 让备份留在本机 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trendi…

2026/11/9 6:51:54 阅读更多 →
51单片机智能定时插座工程实现全链路拆解

51单片机智能定时插座工程实现全链路拆解

简介:本资源是一套面向电子工程初学者与嵌入式开发爱好者的完整实践项目资料,聚焦基于经典51单片机的智能定时插座设计,解决日常电器自动化控制与节能管理需求。资料涵盖原理图设计、C语言源程序(含定时逻辑、按键交互、RTC通信及…

2026/11/6 10:09:23 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/8 1:19:03 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/8 14:17:55 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/9 1:59:56 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/8 1:38:41 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/7 12:08:40 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/8 1:23:14 阅读更多 →

日新闻

周新闻

月新闻