ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Hugo Permalink 令牌全解:从配置到源码的 URL 模式定制指南

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),仅供参考
返回列表