diff --git a/docs/content/en/content-management/urls.md b/docs/content/en/content-management/urls.md index b8cd9a01ab7..e8e50662790 100644 --- a/docs/content/en/content-management/urls.md +++ b/docs/content/en/content-management/urls.md @@ -317,6 +317,14 @@ Use these tokens when defining the URL pattern. You can also use these tokens wh `:slugorfilename` : The slug as defined in front matter, else the content's file name without extension, applicable to the `page` page kind. +`:contentbasename` +: The content base name, as defined in [`File.ContentBaseName`], applicable to pages backed by a file. + +`:contentbasenameorslug` +: The content base name, else the slug as defined above. + +[`File.ContentBaseName`]: /methods/page/file/#contentbasename + For time-related values, you can also use the layout string components defined in Go's [time package]. For example: [time package]: https://pkg.go.dev/time#pkg-constants diff --git a/resources/page/permalinks.go b/resources/page/permalinks.go index ece10bb40e5..56dfff46f30 100644 --- a/resources/page/permalinks.go +++ b/resources/page/permalinks.go @@ -79,19 +79,21 @@ func NewPermalinkExpander(urlize func(uri string) string, patterns map[string]ma } p.knownPermalinkAttributes = map[string]pageToPermaAttribute{ - "year": p.pageToPermalinkDate, - "month": p.pageToPermalinkDate, - "monthname": p.pageToPermalinkDate, - "day": p.pageToPermalinkDate, - "weekday": p.pageToPermalinkDate, - "weekdayname": p.pageToPermalinkDate, - "yearday": p.pageToPermalinkDate, - "section": p.pageToPermalinkSection, - "sections": p.pageToPermalinkSections, - "title": p.pageToPermalinkTitle, - "slug": p.pageToPermalinkSlugElseTitle, - "slugorfilename": p.pageToPermalinkSlugElseFilename, - "filename": p.pageToPermalinkFilename, + "year": p.pageToPermalinkDate, + "month": p.pageToPermalinkDate, + "monthname": p.pageToPermalinkDate, + "day": p.pageToPermalinkDate, + "weekday": p.pageToPermalinkDate, + "weekdayname": p.pageToPermalinkDate, + "yearday": p.pageToPermalinkDate, + "section": p.pageToPermalinkSection, + "sections": p.pageToPermalinkSections, + "title": p.pageToPermalinkTitle, + "slug": p.pageToPermalinkSlugElseTitle, + "slugorfilename": p.pageToPermalinkSlugElseFilename, + "filename": p.pageToPermalinkFilename, + "contentbasename": p.pageToPermalinkContentBaseName, + "contentbasenameorslug": p.pageToPermalinkContentBaseNameOrSlug, } p.expanders = make(map[string]map[string]func(Page) (string, error)) @@ -307,6 +309,26 @@ func (l PermalinkExpander) pageToPermalinkSections(p Page, _ string) (string, er return p.CurrentSection().SectionsPath(), nil } +// pageToPermalinkContentBaseName returns the URL-safe form of the content base name. +func (l PermalinkExpander) pageToPermalinkContentBaseName(p Page, _ string) (string, error) { + if p.File() == nil { + return "", nil + } + return l.urlize(p.File().ContentBaseName()), nil +} + +// pageToPermalinkContentBaseNameOrSlug returns the URL-safe form of the content base name, or the slug. +func (l PermalinkExpander) pageToPermalinkContentBaseNameOrSlug(p Page, a string) (string, error) { + name, err := l.pageToPermalinkContentBaseName(p, a) + if err != nil { + return "", nil + } + if name != "" { + return name, nil + } + return l.pageToPermalinkSlugElseTitle(p, a) +} + func (l PermalinkExpander) translationBaseName(p Page) string { if p.File() == nil { return "" diff --git a/resources/page/permalinks_test.go b/resources/page/permalinks_test.go index 808521f42ef..71c5ded6502 100644 --- a/resources/page/permalinks_test.go +++ b/resources/page/permalinks_test.go @@ -46,6 +46,8 @@ var testdataPermalinks = []struct { {"/:sections[0]/:sections[last]/", true, "/a/c/"}, // Sections {"/\\:filename", true, "/:filename"}, // Escape sequence {"/special\\::slug/", true, "/special:the-slug/"}, // Escape sequence + {"/:contentbasename/", true, "/index/"}, // Content base name + {"/:contentbasenameorslug/", true, "/index/"}, // Content base name or slug // Failures {"/blog/:fred", false, ""},