mirror of
https://github.com/gohugoio/hugo.git
synced 2025-04-28 22:50:35 +03:00
Fix sub-folder baseURL handling for Page resources
I.e. images etc. Fixes #4228
This commit is contained in:
parent
54a89cde69
commit
f25d8a9e17
9 changed files with 136 additions and 52 deletions
|
@ -26,6 +26,10 @@ import (
|
||||||
type PathSpec struct {
|
type PathSpec struct {
|
||||||
BaseURL
|
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
|
disablePathToLower bool
|
||||||
removePathAccents bool
|
removePathAccents bool
|
||||||
uglyURLs bool
|
uglyURLs bool
|
||||||
|
@ -124,6 +128,13 @@ func NewPathSpec(fs *hugofs.Fs, cfg config.Provider) (*PathSpec, error) {
|
||||||
ProcessingStats: NewProcessingStats(lang),
|
ProcessingStats: NewProcessingStats(lang),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !ps.canonifyURLs {
|
||||||
|
basePath := ps.BaseURL.url.Path
|
||||||
|
if basePath != "" && basePath != "/" {
|
||||||
|
ps.BasePath = basePath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
publishDir := ps.AbsPathify(cfg.GetString("publishDir")) + FilePathSeparator
|
publishDir := ps.AbsPathify(cfg.GetString("publishDir")) + FilePathSeparator
|
||||||
// If root, remove the second '/'
|
// If root, remove the second '/'
|
||||||
if publishDir == "//" {
|
if publishDir == "//" {
|
||||||
|
|
|
@ -319,12 +319,11 @@ func AddContextRoot(baseURL, relativePath string) string {
|
||||||
// If canonifyURLs is set, we will globally prepend the absURL with any sub-folder,
|
// If canonifyURLs is set, we will globally prepend the absURL with any sub-folder,
|
||||||
// so avoid doing anything here to avoid getting double paths.
|
// so avoid doing anything here to avoid getting double paths.
|
||||||
func (p *PathSpec) PrependBasePath(rel string) string {
|
func (p *PathSpec) PrependBasePath(rel string) string {
|
||||||
basePath := p.BaseURL.url.Path
|
if p.BasePath != "" {
|
||||||
if !p.canonifyURLs && basePath != "" && basePath != "/" {
|
|
||||||
rel = filepath.ToSlash(rel)
|
rel = filepath.ToSlash(rel)
|
||||||
// Need to prepend any path from the baseURL
|
// Need to prepend any path from the baseURL
|
||||||
hadSlash := strings.HasSuffix(rel, "/")
|
hadSlash := strings.HasSuffix(rel, "/")
|
||||||
rel = path.Join(basePath, rel)
|
rel = path.Join(p.BasePath, rel)
|
||||||
if hadSlash {
|
if hadSlash {
|
||||||
rel += "/"
|
rel += "/"
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,10 +235,11 @@ func doTestMultiSitesBuild(t *testing.T, configTemplate, configSuffix string) {
|
||||||
|
|
||||||
require.Equal(t, "en", enSite.Language.Lang)
|
require.Equal(t, "en", enSite.Language.Lang)
|
||||||
|
|
||||||
if len(enSite.RegularPages) != 4 {
|
if len(enSite.RegularPages) != 5 {
|
||||||
t.Fatal("Expected 4 english pages")
|
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]
|
doc1en := enSite.RegularPages[0]
|
||||||
permalink := doc1en.Permalink()
|
permalink := doc1en.Permalink()
|
||||||
|
@ -291,8 +292,8 @@ func doTestMultiSitesBuild(t *testing.T, configTemplate, configSuffix string) {
|
||||||
frSite := sites.Sites[1]
|
frSite := sites.Sites[1]
|
||||||
|
|
||||||
require.Equal(t, "fr", frSite.Language.Lang)
|
require.Equal(t, "fr", frSite.Language.Lang)
|
||||||
require.Len(t, frSite.RegularPages, 3, "should have 3 pages")
|
require.Len(t, frSite.RegularPages, 4, "should have 3 pages")
|
||||||
require.Len(t, frSite.AllPages, 28, "should have 28 total pages (including translations and nodes)")
|
require.Len(t, frSite.AllPages, 32, "should have 32 total pages (including translations and nodes)")
|
||||||
|
|
||||||
for _, frenchPage := range frSite.RegularPages {
|
for _, frenchPage := range frSite.RegularPages {
|
||||||
require.Equal(t, "fr", frenchPage.Lang())
|
require.Equal(t, "fr", frenchPage.Lang())
|
||||||
|
@ -392,6 +393,25 @@ func doTestMultiSitesBuild(t *testing.T, configTemplate, configSuffix string) {
|
||||||
next = next.Next
|
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) {
|
func TestMultiSitesRebuild(t *testing.T) {
|
||||||
|
@ -420,8 +440,8 @@ func TestMultiSitesRebuild(t *testing.T) {
|
||||||
enSite := sites.Sites[0]
|
enSite := sites.Sites[0]
|
||||||
frSite := sites.Sites[1]
|
frSite := sites.Sites[1]
|
||||||
|
|
||||||
require.Len(t, enSite.RegularPages, 4)
|
require.Len(t, enSite.RegularPages, 5)
|
||||||
require.Len(t, frSite.RegularPages, 3)
|
require.Len(t, frSite.RegularPages, 4)
|
||||||
|
|
||||||
// Verify translations
|
// Verify translations
|
||||||
th.assertFileContent("public/en/sect/doc1-slug/index.html", "Hello")
|
th.assertFileContent("public/en/sect/doc1-slug/index.html", "Hello")
|
||||||
|
@ -449,7 +469,7 @@ func TestMultiSitesRebuild(t *testing.T) {
|
||||||
},
|
},
|
||||||
[]fsnotify.Event{{Name: filepath.FromSlash("content/sect/doc2.en.md"), Op: fsnotify.Remove}},
|
[]fsnotify.Event{{Name: filepath.FromSlash("content/sect/doc2.en.md"), Op: fsnotify.Remove}},
|
||||||
func(t *testing.T) {
|
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
|
// Check build stats
|
||||||
require.Equal(t, 1, enSite.draftCount, "Draft")
|
require.Equal(t, 1, enSite.draftCount, "Draft")
|
||||||
|
@ -472,9 +492,9 @@ func TestMultiSitesRebuild(t *testing.T) {
|
||||||
{Name: filepath.FromSlash("content/new1.fr.md"), Op: fsnotify.Create},
|
{Name: filepath.FromSlash("content/new1.fr.md"), Op: fsnotify.Create},
|
||||||
},
|
},
|
||||||
func(t *testing.T) {
|
func(t *testing.T) {
|
||||||
require.Len(t, enSite.RegularPages, 5)
|
require.Len(t, enSite.RegularPages, 6)
|
||||||
require.Len(t, enSite.AllPages, 30)
|
require.Len(t, enSite.AllPages, 34)
|
||||||
require.Len(t, frSite.RegularPages, 4)
|
require.Len(t, frSite.RegularPages, 5)
|
||||||
require.Equal(t, "new_fr_1", frSite.RegularPages[3].Title)
|
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_2", enSite.RegularPages[0].Title)
|
||||||
require.Equal(t, "new_en_1", enSite.RegularPages[1].Title)
|
require.Equal(t, "new_en_1", enSite.RegularPages[1].Title)
|
||||||
|
@ -492,7 +512,7 @@ func TestMultiSitesRebuild(t *testing.T) {
|
||||||
},
|
},
|
||||||
[]fsnotify.Event{{Name: filepath.FromSlash("content/sect/doc1.en.md"), Op: fsnotify.Write}},
|
[]fsnotify.Event{{Name: filepath.FromSlash("content/sect/doc1.en.md"), Op: fsnotify.Write}},
|
||||||
func(t *testing.T) {
|
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")
|
doc1 := readDestination(t, fs, "public/en/sect/doc1-slug/index.html")
|
||||||
require.True(t, strings.Contains(doc1, "CHANGED"), doc1)
|
require.True(t, strings.Contains(doc1, "CHANGED"), doc1)
|
||||||
|
|
||||||
|
@ -510,7 +530,7 @@ func TestMultiSitesRebuild(t *testing.T) {
|
||||||
{Name: filepath.FromSlash("content/new1.en.md"), Op: fsnotify.Rename},
|
{Name: filepath.FromSlash("content/new1.en.md"), Op: fsnotify.Rename},
|
||||||
},
|
},
|
||||||
func(t *testing.T) {
|
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)
|
require.Equal(t, "new_en_1", enSite.RegularPages[1].Title)
|
||||||
rendered := readDestination(t, fs, "public/en/new1renamed/index.html")
|
rendered := readDestination(t, fs, "public/en/new1renamed/index.html")
|
||||||
require.True(t, strings.Contains(rendered, "new_en_1"), rendered)
|
require.True(t, strings.Contains(rendered, "new_en_1"), rendered)
|
||||||
|
@ -525,9 +545,9 @@ func TestMultiSitesRebuild(t *testing.T) {
|
||||||
},
|
},
|
||||||
[]fsnotify.Event{{Name: filepath.FromSlash("layouts/_default/single.html"), Op: fsnotify.Write}},
|
[]fsnotify.Event{{Name: filepath.FromSlash("layouts/_default/single.html"), Op: fsnotify.Write}},
|
||||||
func(t *testing.T) {
|
func(t *testing.T) {
|
||||||
require.Len(t, enSite.RegularPages, 5)
|
require.Len(t, enSite.RegularPages, 6)
|
||||||
require.Len(t, enSite.AllPages, 30)
|
require.Len(t, enSite.AllPages, 34)
|
||||||
require.Len(t, frSite.RegularPages, 4)
|
require.Len(t, frSite.RegularPages, 5)
|
||||||
doc1 := readDestination(t, fs, "public/en/sect/doc1-slug/index.html")
|
doc1 := readDestination(t, fs, "public/en/sect/doc1-slug/index.html")
|
||||||
require.True(t, strings.Contains(doc1, "Template Changed"), doc1)
|
require.True(t, strings.Contains(doc1, "Template Changed"), doc1)
|
||||||
},
|
},
|
||||||
|
@ -542,9 +562,9 @@ func TestMultiSitesRebuild(t *testing.T) {
|
||||||
},
|
},
|
||||||
[]fsnotify.Event{{Name: filepath.FromSlash("i18n/fr.yaml"), Op: fsnotify.Write}},
|
[]fsnotify.Event{{Name: filepath.FromSlash("i18n/fr.yaml"), Op: fsnotify.Write}},
|
||||||
func(t *testing.T) {
|
func(t *testing.T) {
|
||||||
require.Len(t, enSite.RegularPages, 5)
|
require.Len(t, enSite.RegularPages, 6)
|
||||||
require.Len(t, enSite.AllPages, 30)
|
require.Len(t, enSite.AllPages, 34)
|
||||||
require.Len(t, frSite.RegularPages, 4)
|
require.Len(t, frSite.RegularPages, 5)
|
||||||
docEn := readDestination(t, fs, "public/en/sect/doc1-slug/index.html")
|
docEn := readDestination(t, fs, "public/en/sect/doc1-slug/index.html")
|
||||||
require.True(t, strings.Contains(docEn, "Hello"), "No Hello")
|
require.True(t, strings.Contains(docEn, "Hello"), "No Hello")
|
||||||
docFr := readDestination(t, fs, "public/fr/sect/doc1/index.html")
|
docFr := readDestination(t, fs, "public/fr/sect/doc1/index.html")
|
||||||
|
@ -566,9 +586,9 @@ func TestMultiSitesRebuild(t *testing.T) {
|
||||||
{Name: filepath.FromSlash("layouts/shortcodes/shortcode.html"), Op: fsnotify.Write},
|
{Name: filepath.FromSlash("layouts/shortcodes/shortcode.html"), Op: fsnotify.Write},
|
||||||
},
|
},
|
||||||
func(t *testing.T) {
|
func(t *testing.T) {
|
||||||
require.Len(t, enSite.RegularPages, 5)
|
require.Len(t, enSite.RegularPages, 6)
|
||||||
require.Len(t, enSite.AllPages, 30)
|
require.Len(t, enSite.AllPages, 34)
|
||||||
require.Len(t, frSite.RegularPages, 4)
|
require.Len(t, frSite.RegularPages, 5)
|
||||||
th.assertFileContent("public/fr/sect/doc1/index.html", "Single", "Modified Shortcode: Salut")
|
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")
|
th.assertFileContent("public/en/sect/doc1-slug/index.html", "Single", "Modified Shortcode: Hello")
|
||||||
},
|
},
|
||||||
|
@ -657,8 +677,8 @@ title = "Svenska"
|
||||||
require.Len(t, homeEn.Translations(), 4)
|
require.Len(t, homeEn.Translations(), 4)
|
||||||
require.Equal(t, "sv", homeEn.Translations()[0].Lang())
|
require.Equal(t, "sv", homeEn.Translations()[0].Lang())
|
||||||
|
|
||||||
require.Len(t, enSite.RegularPages, 4)
|
require.Len(t, enSite.RegularPages, 5)
|
||||||
require.Len(t, frSite.RegularPages, 3)
|
require.Len(t, frSite.RegularPages, 4)
|
||||||
|
|
||||||
// Veriy Swedish site
|
// Veriy Swedish site
|
||||||
require.Len(t, svSite.RegularPages, 1)
|
require.Len(t, svSite.RegularPages, 1)
|
||||||
|
@ -1241,6 +1261,24 @@ lag:
|
||||||
- Sogndal
|
- Sogndal
|
||||||
---
|
---
|
||||||
# Tax NB
|
# 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
|
||||||
`},
|
`},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1309,7 +1347,7 @@ func readFileFromFs(t testing.TB, fs afero.Fs, filename string) string {
|
||||||
b, err := afero.ReadFile(fs, filename)
|
b, err := afero.ReadFile(fs, filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Print some debug info
|
// 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 {
|
afero.Walk(fs, root, func(path string, info os.FileInfo, err error) error {
|
||||||
if info != nil && !info.IsDir() {
|
if info != nil && !info.IsDir() {
|
||||||
fmt.Println(" ", path)
|
fmt.Println(" ", path)
|
||||||
|
|
|
@ -225,9 +225,12 @@ type Page struct {
|
||||||
Sitemap Sitemap
|
Sitemap Sitemap
|
||||||
|
|
||||||
URLPath
|
URLPath
|
||||||
permalink string
|
permalink string
|
||||||
relPermalink string
|
relPermalink string
|
||||||
relPermalinkBase string // relPermalink without extension
|
|
||||||
|
// 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
|
layoutDescriptor output.LayoutDescriptor
|
||||||
|
|
||||||
|
|
|
@ -137,9 +137,9 @@ func (p *Page) initURLs() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
rel = p.s.PathSpec.PrependBasePath(rel)
|
|
||||||
p.relPermalink = rel
|
|
||||||
p.relPermalinkBase = strings.TrimSuffix(rel, f.MediaType.FullSuffix())
|
p.relPermalinkBase = strings.TrimSuffix(rel, f.MediaType.FullSuffix())
|
||||||
|
p.relPermalink = p.s.PathSpec.PrependBasePath(rel)
|
||||||
p.layoutDescriptor = p.createLayoutDescriptor()
|
p.layoutDescriptor = p.createLayoutDescriptor()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ type Image struct {
|
||||||
configInit sync.Once
|
configInit sync.Once
|
||||||
configLoaded bool
|
configLoaded bool
|
||||||
|
|
||||||
copiedToDestinationInit sync.Once
|
copyToDestinationInit sync.Once
|
||||||
|
|
||||||
imaging *Imaging
|
imaging *Imaging
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ func (i *Image) doWithImageConfig(action, spec string, f func(src image.Image, c
|
||||||
conf.Filter = imageFilters[conf.FilterStr]
|
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) {
|
return i.spec.imageCache.getOrCreate(i.spec, key, func(resourceCacheFilename string) (*Image, error) {
|
||||||
ci := i.clone()
|
ci := i.clone()
|
||||||
|
@ -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.config = image.Config{Width: b.Max.X, Height: b.Max.Y}
|
||||||
ci.configLoaded = true
|
ci.configLoaded = true
|
||||||
|
|
||||||
return ci, i.encodeToDestinations(converted, conf, resourceCacheFilename, ci.RelPermalink())
|
return ci, i.encodeToDestinations(converted, conf, resourceCacheFilename, ci.target())
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -392,8 +392,8 @@ func (i *Image) decodeSource() (image.Image, error) {
|
||||||
func (i *Image) copyToDestination(src string) error {
|
func (i *Image) copyToDestination(src string) error {
|
||||||
var res error
|
var res error
|
||||||
|
|
||||||
i.copiedToDestinationInit.Do(func() {
|
i.copyToDestinationInit.Do(func() {
|
||||||
target := filepath.Join(i.absPublishDir, i.RelPermalink())
|
target := filepath.Join(i.absPublishDir, i.target())
|
||||||
|
|
||||||
// Fast path:
|
// Fast path:
|
||||||
// This is a processed version of the original.
|
// This is a processed version of the original.
|
||||||
|
|
|
@ -219,11 +219,11 @@ type genericResource struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *genericResource) Permalink() string {
|
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 {
|
func (l *genericResource) RelPermalink() string {
|
||||||
return l.relPermalinkForRel(l.rel)
|
return l.relPermalinkForRel(l.rel, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement the Cloner interface.
|
// Implement the Cloner interface.
|
||||||
|
@ -232,16 +232,21 @@ func (l genericResource) WithNewBase(base string) Resource {
|
||||||
return &l
|
return &l
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *genericResource) relPermalinkForRel(rel string) string {
|
func (l *genericResource) relPermalinkForRel(rel string, addBasePath bool) string {
|
||||||
if l.link != nil {
|
if l.link != nil {
|
||||||
rel = l.link(rel)
|
rel = l.link(rel)
|
||||||
}
|
}
|
||||||
|
|
||||||
if l.base != "" {
|
if l.base != "" {
|
||||||
rel = path.Join(l.base, rel)
|
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)
|
return l.spec.PathSpec.URLizeFilename(rel)
|
||||||
|
@ -262,11 +267,15 @@ func (l *genericResource) Publish() error {
|
||||||
}
|
}
|
||||||
defer f.Close()
|
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)
|
return helpers.WriteToDisk(target, f, l.spec.Fs.Destination)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *genericResource) target() string {
|
||||||
|
return l.relPermalinkForRel(l.rel, false)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Spec) newGenericResource(
|
func (r *Spec) newGenericResource(
|
||||||
linker func(base string) string,
|
linker func(base string) string,
|
||||||
osFileInfo os.FileInfo,
|
osFileInfo os.FileInfo,
|
||||||
|
|
|
@ -28,7 +28,7 @@ func TestGenericResource(t *testing.T) {
|
||||||
r := spec.newGenericResource(nil, nil, "/public", "/a/foo.css", "foo.css", "css")
|
r := spec.newGenericResource(nil, nil, "/public", "/a/foo.css", "foo.css", "css")
|
||||||
|
|
||||||
assert.Equal("https://example.com/foo.css", r.Permalink())
|
assert.Equal("https://example.com/foo.css", r.Permalink())
|
||||||
assert.Equal("foo.css", r.RelPermalink())
|
assert.Equal("/foo.css", r.RelPermalink())
|
||||||
assert.Equal("css", r.ResourceType())
|
assert.Equal("css", r.ResourceType())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ func TestNewResourceFromFilename(t *testing.T) {
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.NotNil(r)
|
assert.NotNil(r)
|
||||||
assert.Equal("image", r.ResourceType())
|
assert.Equal("image", r.ResourceType())
|
||||||
assert.Equal("a/b/logo.png", r.RelPermalink())
|
assert.Equal("/a/b/logo.png", r.RelPermalink())
|
||||||
assert.Equal("https://example.com/a/b/logo.png", r.Permalink())
|
assert.Equal("https://example.com/a/b/logo.png", r.Permalink())
|
||||||
|
|
||||||
r, err = spec.NewResourceFromFilename(nil, "/public", "/root/a/b/data.json", "a/b/data.json")
|
r, err = spec.NewResourceFromFilename(nil, "/public", "/root/a/b/data.json", "a/b/data.json")
|
||||||
|
@ -74,6 +74,25 @@ func TestNewResourceFromFilename(t *testing.T) {
|
||||||
assert.Equal("/aceof/a/b/data.json", cloned.RelPermalink())
|
assert.Equal("/aceof/a/b/data.json", cloned.RelPermalink())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewResourceFromFilenameSubPathInBaseURL(t *testing.T) {
|
||||||
|
assert := require.New(t)
|
||||||
|
spec := newTestResourceSpecForBaseURL(assert, "https://example.com/docs")
|
||||||
|
|
||||||
|
writeSource(t, spec.Fs, "/project/a/b/logo.png", "image")
|
||||||
|
|
||||||
|
r, err := spec.NewResourceFromFilename(nil, "/public",
|
||||||
|
filepath.FromSlash("/project/a/b/logo.png"), filepath.FromSlash("a/b/logo.png"))
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(r)
|
||||||
|
assert.Equal("image", r.ResourceType())
|
||||||
|
assert.Equal("/docs/a/b/logo.png", r.RelPermalink())
|
||||||
|
assert.Equal("https://example.com/docs/a/b/logo.png", r.Permalink())
|
||||||
|
img := r.(*Image)
|
||||||
|
assert.Equal("/a/b/logo.png", img.target())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestResourcesByType(t *testing.T) {
|
func TestResourcesByType(t *testing.T) {
|
||||||
assert := require.New(t)
|
assert := require.New(t)
|
||||||
spec := newTestResourceSpec(assert)
|
spec := newTestResourceSpec(assert)
|
||||||
|
@ -99,10 +118,10 @@ func TestResourcesGetByPrefix(t *testing.T) {
|
||||||
spec.newGenericResource(nil, nil, "/public", "/b/foo3.css", "foo3.css", "css")}
|
spec.newGenericResource(nil, nil, "/public", "/b/foo3.css", "foo3.css", "css")}
|
||||||
|
|
||||||
assert.Nil(resources.GetByPrefix("asdf"))
|
assert.Nil(resources.GetByPrefix("asdf"))
|
||||||
assert.Equal("logo1.png", resources.GetByPrefix("logo").RelPermalink())
|
assert.Equal("/logo1.png", resources.GetByPrefix("logo").RelPermalink())
|
||||||
assert.Equal("foo2.css", resources.GetByPrefix("foo2").RelPermalink())
|
assert.Equal("/foo2.css", resources.GetByPrefix("foo2").RelPermalink())
|
||||||
assert.Equal("foo1.css", resources.GetByPrefix("foo1").RelPermalink())
|
assert.Equal("/foo1.css", resources.GetByPrefix("foo1").RelPermalink())
|
||||||
assert.Equal("foo1.css", resources.GetByPrefix("foo1").RelPermalink())
|
assert.Equal("/foo1.css", resources.GetByPrefix("foo1").RelPermalink())
|
||||||
assert.Nil(resources.GetByPrefix("asdfasdf"))
|
assert.Nil(resources.GetByPrefix("asdfasdf"))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,17 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func newTestResourceSpec(assert *require.Assertions) *Spec {
|
func newTestResourceSpec(assert *require.Assertions) *Spec {
|
||||||
|
return newTestResourceSpecForBaseURL(assert, "https://example.com/")
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTestResourceSpecForBaseURL(assert *require.Assertions, baseURL string) *Spec {
|
||||||
cfg := viper.New()
|
cfg := viper.New()
|
||||||
cfg.Set("baseURL", "https://example.com/")
|
cfg.Set("baseURL", baseURL)
|
||||||
cfg.Set("resourceDir", "/res")
|
cfg.Set("resourceDir", "/res")
|
||||||
fs := hugofs.NewMem(cfg)
|
fs := hugofs.NewMem(cfg)
|
||||||
|
|
||||||
s, err := helpers.NewPathSpec(fs, cfg)
|
s, err := helpers.NewPathSpec(fs, cfg)
|
||||||
|
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
spec, err := NewSpec(s, media.DefaultTypes)
|
spec, err := NewSpec(s, media.DefaultTypes)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue