Skip to content

Commit

Permalink
Fix sub-folder baseURL handling for Page resources
Browse files Browse the repository at this point in the history
I.e. images etc.

Fixes #4228
  • Loading branch information
bep committed Jan 6, 2018
1 parent 54a89cd commit f25d8a9
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 52 deletions.
11 changes: 11 additions & 0 deletions helpers/pathspec.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ import (
type PathSpec struct {
BaseURL

// If the baseURL contains a base path, e.g. https://example.com/docs, then "/docs" will be the BasePath.
// This will not be set if canonifyURLs is enabled.
BasePath string

disablePathToLower bool
removePathAccents bool
uglyURLs bool
Expand Down Expand Up @@ -124,6 +128,13 @@ func NewPathSpec(fs *hugofs.Fs, cfg config.Provider) (*PathSpec, error) {
ProcessingStats: NewProcessingStats(lang),
}

if !ps.canonifyURLs {
basePath := ps.BaseURL.url.Path
if basePath != "" && basePath != "/" {
ps.BasePath = basePath
}
}

publishDir := ps.AbsPathify(cfg.GetString("publishDir")) + FilePathSeparator
// If root, remove the second '/'
if publishDir == "//" {
Expand Down
5 changes: 2 additions & 3 deletions helpers/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,12 +319,11 @@ func AddContextRoot(baseURL, relativePath string) string {
// If canonifyURLs is set, we will globally prepend the absURL with any sub-folder,
// so avoid doing anything here to avoid getting double paths.
func (p *PathSpec) PrependBasePath(rel string) string {
basePath := p.BaseURL.url.Path
if !p.canonifyURLs && basePath != "" && basePath != "/" {
if p.BasePath != "" {
rel = filepath.ToSlash(rel)
// Need to prepend any path from the baseURL
hadSlash := strings.HasSuffix(rel, "/")
rel = path.Join(basePath, rel)
rel = path.Join(p.BasePath, rel)
if hadSlash {
rel += "/"
}
Expand Down
88 changes: 63 additions & 25 deletions hugolib/hugo_sites_build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,11 @@ func doTestMultiSitesBuild(t *testing.T, configTemplate, configSuffix string) {

require.Equal(t, "en", enSite.Language.Lang)

if len(enSite.RegularPages) != 4 {
t.Fatal("Expected 4 english pages")
if len(enSite.RegularPages) != 5 {
t.Fatal("Expected 5 english pages")
}
require.Len(t, enSite.AllPages, 28, "should have 28 total pages (including translations and index types)")

require.Len(t, enSite.AllPages, 32, "should have 32 total pages (including translations and index types)")

doc1en := enSite.RegularPages[0]
permalink := doc1en.Permalink()
Expand Down Expand Up @@ -291,8 +292,8 @@ func doTestMultiSitesBuild(t *testing.T, configTemplate, configSuffix string) {
frSite := sites.Sites[1]

require.Equal(t, "fr", frSite.Language.Lang)
require.Len(t, frSite.RegularPages, 3, "should have 3 pages")
require.Len(t, frSite.AllPages, 28, "should have 28 total pages (including translations and nodes)")
require.Len(t, frSite.RegularPages, 4, "should have 3 pages")
require.Len(t, frSite.AllPages, 32, "should have 32 total pages (including translations and nodes)")

for _, frenchPage := range frSite.RegularPages {
require.Equal(t, "fr", frenchPage.Lang())
Expand Down Expand Up @@ -392,6 +393,25 @@ func doTestMultiSitesBuild(t *testing.T, configTemplate, configSuffix string) {
next = next.Next
}

// Check bundles
bundleFr := enSite.getPage(KindPage, "bundles/b1/index.md")
require.NotNil(t, bundleFr)
require.Equal(t, "/blog/fr/bundles/b1/", bundleFr.RelPermalink())
require.Equal(t, 1, len(bundleFr.Resources))
logoFr := bundleFr.Resources.GetByPrefix("logo")
require.NotNil(t, logoFr)
require.Equal(t, "/blog/fr/bundles/b1/logo.png", logoFr.RelPermalink())
require.Contains(t, readFileFromFs(t, fs.Destination, filepath.FromSlash("public/fr/bundles/b1/logo.png")), "PNG Data")

bundleEn := enSite.getPage(KindPage, "bundles/b1/index.en.md")
require.NotNil(t, bundleEn)
require.Equal(t, "/blog/en/bundles/b1/", bundleEn.RelPermalink())
require.Equal(t, 1, len(bundleEn.Resources))
logoEn := bundleEn.Resources.GetByPrefix("logo")
require.NotNil(t, logoEn)
require.Equal(t, "/blog/en/bundles/b1/logo.png", logoEn.RelPermalink())
require.Contains(t, readFileFromFs(t, fs.Destination, filepath.FromSlash("public/en/bundles/b1/logo.png")), "PNG Data")

}

func TestMultiSitesRebuild(t *testing.T) {
Expand Down Expand Up @@ -420,8 +440,8 @@ func TestMultiSitesRebuild(t *testing.T) {
enSite := sites.Sites[0]
frSite := sites.Sites[1]

require.Len(t, enSite.RegularPages, 4)
require.Len(t, frSite.RegularPages, 3)
require.Len(t, enSite.RegularPages, 5)
require.Len(t, frSite.RegularPages, 4)

// Verify translations
th.assertFileContent("public/en/sect/doc1-slug/index.html", "Hello")
Expand Down Expand Up @@ -449,7 +469,7 @@ func TestMultiSitesRebuild(t *testing.T) {
},
[]fsnotify.Event{{Name: filepath.FromSlash("content/sect/doc2.en.md"), Op: fsnotify.Remove}},
func(t *testing.T) {
require.Len(t, enSite.RegularPages, 3, "1 en removed")
require.Len(t, enSite.RegularPages, 4, "1 en removed")

// Check build stats
require.Equal(t, 1, enSite.draftCount, "Draft")
Expand All @@ -472,9 +492,9 @@ func TestMultiSitesRebuild(t *testing.T) {
{Name: filepath.FromSlash("content/new1.fr.md"), Op: fsnotify.Create},
},
func(t *testing.T) {
require.Len(t, enSite.RegularPages, 5)
require.Len(t, enSite.AllPages, 30)
require.Len(t, frSite.RegularPages, 4)
require.Len(t, enSite.RegularPages, 6)
require.Len(t, enSite.AllPages, 34)
require.Len(t, frSite.RegularPages, 5)
require.Equal(t, "new_fr_1", frSite.RegularPages[3].Title)
require.Equal(t, "new_en_2", enSite.RegularPages[0].Title)
require.Equal(t, "new_en_1", enSite.RegularPages[1].Title)
Expand All @@ -492,7 +512,7 @@ func TestMultiSitesRebuild(t *testing.T) {
},
[]fsnotify.Event{{Name: filepath.FromSlash("content/sect/doc1.en.md"), Op: fsnotify.Write}},
func(t *testing.T) {
require.Len(t, enSite.RegularPages, 5)
require.Len(t, enSite.RegularPages, 6)
doc1 := readDestination(t, fs, "public/en/sect/doc1-slug/index.html")
require.True(t, strings.Contains(doc1, "CHANGED"), doc1)

Expand All @@ -510,7 +530,7 @@ func TestMultiSitesRebuild(t *testing.T) {
{Name: filepath.FromSlash("content/new1.en.md"), Op: fsnotify.Rename},
},
func(t *testing.T) {
require.Len(t, enSite.RegularPages, 5, "Rename")
require.Len(t, enSite.RegularPages, 6, "Rename")
require.Equal(t, "new_en_1", enSite.RegularPages[1].Title)
rendered := readDestination(t, fs, "public/en/new1renamed/index.html")
require.True(t, strings.Contains(rendered, "new_en_1"), rendered)
Expand All @@ -525,9 +545,9 @@ func TestMultiSitesRebuild(t *testing.T) {
},
[]fsnotify.Event{{Name: filepath.FromSlash("layouts/_default/single.html"), Op: fsnotify.Write}},
func(t *testing.T) {
require.Len(t, enSite.RegularPages, 5)
require.Len(t, enSite.AllPages, 30)
require.Len(t, frSite.RegularPages, 4)
require.Len(t, enSite.RegularPages, 6)
require.Len(t, enSite.AllPages, 34)
require.Len(t, frSite.RegularPages, 5)
doc1 := readDestination(t, fs, "public/en/sect/doc1-slug/index.html")
require.True(t, strings.Contains(doc1, "Template Changed"), doc1)
},
Expand All @@ -542,9 +562,9 @@ func TestMultiSitesRebuild(t *testing.T) {
},
[]fsnotify.Event{{Name: filepath.FromSlash("i18n/fr.yaml"), Op: fsnotify.Write}},
func(t *testing.T) {
require.Len(t, enSite.RegularPages, 5)
require.Len(t, enSite.AllPages, 30)
require.Len(t, frSite.RegularPages, 4)
require.Len(t, enSite.RegularPages, 6)
require.Len(t, enSite.AllPages, 34)
require.Len(t, frSite.RegularPages, 5)
docEn := readDestination(t, fs, "public/en/sect/doc1-slug/index.html")
require.True(t, strings.Contains(docEn, "Hello"), "No Hello")
docFr := readDestination(t, fs, "public/fr/sect/doc1/index.html")
Expand All @@ -566,9 +586,9 @@ func TestMultiSitesRebuild(t *testing.T) {
{Name: filepath.FromSlash("layouts/shortcodes/shortcode.html"), Op: fsnotify.Write},
},
func(t *testing.T) {
require.Len(t, enSite.RegularPages, 5)
require.Len(t, enSite.AllPages, 30)
require.Len(t, frSite.RegularPages, 4)
require.Len(t, enSite.RegularPages, 6)
require.Len(t, enSite.AllPages, 34)
require.Len(t, frSite.RegularPages, 5)
th.assertFileContent("public/fr/sect/doc1/index.html", "Single", "Modified Shortcode: Salut")
th.assertFileContent("public/en/sect/doc1-slug/index.html", "Single", "Modified Shortcode: Hello")
},
Expand Down Expand Up @@ -657,8 +677,8 @@ title = "Svenska"
require.Len(t, homeEn.Translations(), 4)
require.Equal(t, "sv", homeEn.Translations()[0].Lang())

require.Len(t, enSite.RegularPages, 4)
require.Len(t, frSite.RegularPages, 3)
require.Len(t, enSite.RegularPages, 5)
require.Len(t, frSite.RegularPages, 4)

// Veriy Swedish site
require.Len(t, svSite.RegularPages, 1)
Expand Down Expand Up @@ -1241,6 +1261,24 @@ lag:
- Sogndal
---
# Tax NB
`},
// Bundle
{filepath.FromSlash("bundles/b1/index.en.md"), `---
title: Bundle EN
publishdate: "2000-01-06"
weight: 2001
---
# Bundle Content EN
`},
{filepath.FromSlash("bundles/b1/index.md"), `---
title: Bundle Default
publishdate: "2000-01-06"
weight: 2002
---
# Bundle Content Default
`},
{filepath.FromSlash("bundles/b1/logo.png"), `
PNG Data
`},
}

Expand Down Expand Up @@ -1309,7 +1347,7 @@ func readFileFromFs(t testing.TB, fs afero.Fs, filename string) string {
b, err := afero.ReadFile(fs, filename)
if err != nil {
// Print some debug info
root := "/" //strings.Split(filename, helpers.FilePathSeparator)[0]
root := "" //strings.Split(filename, helpers.FilePathSeparator)[0]
afero.Walk(fs, root, func(path string, info os.FileInfo, err error) error {
if info != nil && !info.IsDir() {
fmt.Println(" ", path)
Expand Down
9 changes: 6 additions & 3 deletions hugolib/page.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,12 @@ type Page struct {
Sitemap Sitemap

URLPath
permalink string
relPermalink string
relPermalinkBase string // relPermalink without extension
permalink string
relPermalink string

// relPermalink without extension and any base path element from the baseURL.
// This is used to construct paths in the page resources.
relPermalinkBase string

layoutDescriptor output.LayoutDescriptor

Expand Down
4 changes: 2 additions & 2 deletions hugolib/page_paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,9 @@ func (p *Page) initURLs() error {
if err != nil {
return err
}
rel = p.s.PathSpec.PrependBasePath(rel)
p.relPermalink = rel

p.relPermalinkBase = strings.TrimSuffix(rel, f.MediaType.FullSuffix())
p.relPermalink = p.s.PathSpec.PrependBasePath(rel)
p.layoutDescriptor = p.createLayoutDescriptor()
return nil
}
Expand Down
10 changes: 5 additions & 5 deletions resource/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ type Image struct {
configInit sync.Once
configLoaded bool

copiedToDestinationInit sync.Once
copyToDestinationInit sync.Once

imaging *Imaging

Expand Down Expand Up @@ -206,7 +206,7 @@ func (i *Image) doWithImageConfig(action, spec string, f func(src image.Image, c
conf.Filter = imageFilters[conf.FilterStr]
}

key := i.relPermalinkForRel(i.filenameFromConfig(conf))
key := i.relPermalinkForRel(i.filenameFromConfig(conf), false)

return i.spec.imageCache.getOrCreate(i.spec, key, func(resourceCacheFilename string) (*Image, error) {
ci := i.clone()
Expand All @@ -232,7 +232,7 @@ func (i *Image) doWithImageConfig(action, spec string, f func(src image.Image, c
ci.config = image.Config{Width: b.Max.X, Height: b.Max.Y}
ci.configLoaded = true

return ci, i.encodeToDestinations(converted, conf, resourceCacheFilename, ci.RelPermalink())
return ci, i.encodeToDestinations(converted, conf, resourceCacheFilename, ci.target())
})

}
Expand Down Expand Up @@ -392,8 +392,8 @@ func (i *Image) decodeSource() (image.Image, error) {
func (i *Image) copyToDestination(src string) error {
var res error

i.copiedToDestinationInit.Do(func() {
target := filepath.Join(i.absPublishDir, i.RelPermalink())
i.copyToDestinationInit.Do(func() {
target := filepath.Join(i.absPublishDir, i.target())

// Fast path:
// This is a processed version of the original.
Expand Down
23 changes: 16 additions & 7 deletions resource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,11 @@ type genericResource struct {
}

func (l *genericResource) Permalink() string {
return l.spec.PermalinkForBaseURL(l.RelPermalink(), l.spec.BaseURL.String())
return l.spec.PermalinkForBaseURL(l.relPermalinkForRel(l.rel, false), l.spec.BaseURL.String())
}

func (l *genericResource) RelPermalink() string {
return l.relPermalinkForRel(l.rel)
return l.relPermalinkForRel(l.rel, true)
}

// Implement the Cloner interface.
Expand All @@ -232,16 +232,21 @@ func (l genericResource) WithNewBase(base string) Resource {
return &l
}

func (l *genericResource) relPermalinkForRel(rel string) string {
func (l *genericResource) relPermalinkForRel(rel string, addBasePath bool) string {
if l.link != nil {
rel = l.link(rel)
}

if l.base != "" {
rel = path.Join(l.base, rel)
if rel[0] != '/' {
rel = "/" + rel
}
}

if addBasePath && l.spec.PathSpec.BasePath != "" {
rel = path.Join(l.spec.PathSpec.BasePath, rel)
}

if rel[0] != '/' {
rel = "/" + rel
}

return l.spec.PathSpec.URLizeFilename(rel)
Expand All @@ -262,11 +267,15 @@ func (l *genericResource) Publish() error {
}
defer f.Close()

target := filepath.Join(l.absPublishDir, l.RelPermalink())
target := filepath.Join(l.absPublishDir, l.target())

return helpers.WriteToDisk(target, f, l.spec.Fs.Destination)
}

func (l *genericResource) target() string {
return l.relPermalinkForRel(l.rel, false)
}

func (r *Spec) newGenericResource(
linker func(base string) string,
osFileInfo os.FileInfo,
Expand Down
Loading

0 comments on commit f25d8a9

Please sign in to comment.