hugolib: Support sub-sections in permalink settings

This enables both the variants below:

Current (first level only):

```
"blog": ":section/:title",
```

Nested (all levels):

```
"blog": ":sections/:title",
```

Should ideally been part of Hugo 0.22, but better late than never ...

Fixes #3580
This commit is contained in:
Bjørn Erik Pedersen 2017-06-12 19:14:29 +02:00
parent ff54b6bddc
commit 1f26420d39
2 changed files with 35 additions and 2 deletions

View file

@ -16,6 +16,7 @@ package hugolib
import ( import (
"errors" "errors"
"fmt" "fmt"
"path"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
@ -182,6 +183,12 @@ func pageToPermalinkSection(p *Page, _ string) (string, error) {
return p.Section(), nil return p.Section(), nil
} }
func pageToPermalinkSections(p *Page, _ string) (string, error) {
// TODO(bep) we have some superflous URLize in this file, but let's
// deal with that later.
return path.Join(p.current().sections...), nil
}
func init() { func init() {
knownPermalinkAttributes = map[string]pageToPermaAttribute{ knownPermalinkAttributes = map[string]pageToPermaAttribute{
"year": pageToPermalinkDate, "year": pageToPermalinkDate,
@ -192,6 +199,7 @@ func init() {
"weekdayname": pageToPermalinkDate, "weekdayname": pageToPermalinkDate,
"yearday": pageToPermalinkDate, "yearday": pageToPermalinkDate,
"section": pageToPermalinkSection, "section": pageToPermalinkSection,
"sections": pageToPermalinkSections,
"title": pageToPermalinkTitle, "title": pageToPermalinkTitle,
"slug": pageToPermalinkSlugElseTitle, "slug": pageToPermalinkSlugElseTitle,
"filename": pageToPermalinkFilename, "filename": pageToPermalinkFilename,

View file

@ -32,6 +32,10 @@ func TestNestedSections(t *testing.T) {
th = testHelper{cfg, fs, t} th = testHelper{cfg, fs, t}
) )
cfg.Set("permalinks", map[string]string{
"perm a": ":sections/:title",
})
pageTemplate := `--- pageTemplate := `---
title: T%d_%d title: T%d_%d
--- ---
@ -64,6 +68,15 @@ Content
writeSource(t, fs, filepath.Join("content", "empty3", "b", "c", "d", "_index.md"), fmt.Sprintf(pageTemplate, 41, -1)) writeSource(t, fs, filepath.Join("content", "empty3", "b", "c", "d", "_index.md"), fmt.Sprintf(pageTemplate, 41, -1))
writeSource(t, fs, filepath.Join("content", "empty3", "b", "empty3.md"), fmt.Sprintf(pageTemplate, 3, -1)) writeSource(t, fs, filepath.Join("content", "empty3", "b", "empty3.md"), fmt.Sprintf(pageTemplate, 3, -1))
// Section with permalink config
writeSource(t, fs, filepath.Join("content", "perm a", "link", "_index.md"), fmt.Sprintf(pageTemplate, 9, -1))
for i := 1; i < 4; i++ {
writeSource(t, fs, filepath.Join("content", "perm a", "link", fmt.Sprintf("page_%d.md", i)),
fmt.Sprintf(pageTemplate, 1, i))
}
writeSource(t, fs, filepath.Join("content", "perm a", "link", "regular", fmt.Sprintf("page_%d.md", 5)),
fmt.Sprintf(pageTemplate, 1, 5))
writeSource(t, fs, filepath.Join("content", "l1", "l2", "_index.md"), fmt.Sprintf(pageTemplate, 2, -1)) writeSource(t, fs, filepath.Join("content", "l1", "l2", "_index.md"), fmt.Sprintf(pageTemplate, 2, -1))
writeSource(t, fs, filepath.Join("content", "l1", "l2_2", "_index.md"), fmt.Sprintf(pageTemplate, 22, -1)) writeSource(t, fs, filepath.Join("content", "l1", "l2_2", "_index.md"), fmt.Sprintf(pageTemplate, 22, -1))
writeSource(t, fs, filepath.Join("content", "l1", "l2", "l3", "_index.md"), fmt.Sprintf(pageTemplate, 3, -1)) writeSource(t, fs, filepath.Join("content", "l1", "l2", "l3", "_index.md"), fmt.Sprintf(pageTemplate, 3, -1))
@ -96,7 +109,7 @@ PAG|{{ .Title }}|{{ $sect.InSection . }}
cfg.Set("paginate", 2) cfg.Set("paginate", 2)
s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{}) s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{})
require.Len(t, s.RegularPages, 14) require.Len(t, s.RegularPages, 18)
tests := []struct { tests := []struct {
sections string sections string
@ -185,6 +198,18 @@ PAG|{{ .Title }}|{{ $sect.InSection . }}
assert.Equal("T2_-1", p.Parent().Title) assert.Equal("T2_-1", p.Parent().Title)
assert.Len(p.Sections(), 0) assert.Len(p.Sections(), 0)
}}, }},
{"perm a,link", func(p *Page) {
assert.Equal("T9_-1", p.Title)
assert.Equal("/perm-a/link/", p.RelPermalink())
assert.Len(p.Pages, 4)
first := p.Pages[0]
assert.Equal("/perm-a/link/t1_1/", first.RelPermalink())
th.assertFileContent("public/perm-a/link/t1_1/index.html", "Single|T1_1")
last := p.Pages[3]
assert.Equal("/perm-a/link/t1_5/", last.RelPermalink())
}},
} }
for _, test := range tests { for _, test := range tests {
@ -203,7 +228,7 @@ PAG|{{ .Title }}|{{ $sect.InSection . }}
assert.NotNil(home) assert.NotNil(home)
assert.Len(home.Sections(), 6) assert.Len(home.Sections(), 7)
rootPage := s.getPage(KindPage, "mypage.md") rootPage := s.getPage(KindPage, "mypage.md")
assert.NotNil(rootPage) assert.NotNil(rootPage)