diff --git a/hugolib/alias.go b/hugolib/alias.go index b97094ecc..c1f668d41 100644 --- a/hugolib/alias.go +++ b/hugolib/alias.go @@ -99,8 +99,11 @@ func (s *Site) publishDestAlias(allowRoot bool, path, permalink string, outputFo OutputFormat: outputFormat, } - return s.publisher.Publish(pd) + if s.Info.relativeURLs || s.Info.canonifyURLs { + pd.AbsURLPath = s.absURLPath(targetPath) + } + return s.publisher.Publish(pd) } func (a aliasHandler) targetPathAlias(src string) (string, error) { diff --git a/hugolib/alias_test.go b/hugolib/alias_test.go index b0491c13e..17c663496 100644 --- a/hugolib/alias_test.go +++ b/hugolib/alias_test.go @@ -45,18 +45,29 @@ func TestAlias(t *testing.T) { t.Parallel() c := qt.New(t) - b := newTestSitesBuilder(t) - b.WithSimpleConfigFile().WithContent("blog/page.md", pageWithAlias) - b.CreateSites().Build(BuildCfg{}) + tests := []struct { + urlPrefix string + settings map[string]interface{} + }{ + {"http://example.com", map[string]interface{}{"baseURL": "http://example.com"}}, + {"http://example.com", map[string]interface{}{"baseURL": "http://example.com", "canonifyURLs": true}}, + {"../..", map[string]interface{}{"relativeURLs": true}}, + } - c.Assert(len(b.H.Sites), qt.Equals, 1) - c.Assert(len(b.H.Sites[0].RegularPages()), qt.Equals, 1) + for _, test := range tests { + b := newTestSitesBuilder(t) + b.WithSimpleConfigFileAndSettings(test.settings).WithContent("blog/page.md", pageWithAlias) + b.CreateSites().Build(BuildCfg{}) - // the real page - b.AssertFileContent("public/blog/page/index.html", "For some moments the old man") - // the alias redirectors - b.AssertFileContent("public/foo/bar/index.html", "") + b.AssertFileContent("public/blog/rel/index.html", "") + } } func TestAliasMultipleOutputFormats(t *testing.T) { diff --git a/hugolib/site.go b/hugolib/site.go index 34671443e..d544cb095 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -1540,7 +1540,21 @@ func (s *SiteInfo) GetPage(ref ...string) (page.Page, error) { func (s *Site) permalink(link string) string { return s.PathSpec.PermalinkForBaseURL(link, s.PathSpec.BaseURL.String()) +} +func (s *Site) absURLPath(targetPath string) string { + var path string + if s.Info.relativeURLs { + path = helpers.GetDottedRelativePath(targetPath) + } else { + url := s.PathSpec.BaseURL.String() + if !strings.HasSuffix(url, "/") { + url += "/" + } + path = url + } + + return path } func (s *Site) lookupLayouts(layouts ...string) tpl.Template { @@ -1562,17 +1576,6 @@ func (s *Site) renderAndWriteXML(statCounter *uint64, name string, targetPath st return err } - var path string - if s.Info.relativeURLs { - path = helpers.GetDottedRelativePath(targetPath) - } else { - s := s.PathSpec.BaseURL.String() - if !strings.HasSuffix(s, "/") { - s += "/" - } - path = s - } - pd := publisher.Descriptor{ Src: renderBuffer, TargetPath: targetPath, @@ -1580,14 +1583,14 @@ func (s *Site) renderAndWriteXML(statCounter *uint64, name string, targetPath st // For the minification part of XML, // we currently only use the MIME type. OutputFormat: output.RSSFormat, - AbsURLPath: path, + AbsURLPath: s.absURLPath(targetPath), } return s.publisher.Publish(pd) - } func (s *Site) renderAndWritePage(statCounter *uint64, name string, targetPath string, p *pageState, templ tpl.Template) error { + s.Log.DEBUG.Printf("Render %s to %q", name, targetPath) renderBuffer := bp.GetBuffer() defer bp.PutBuffer(renderBuffer) @@ -1604,18 +1607,6 @@ func (s *Site) renderAndWritePage(statCounter *uint64, name string, targetPath s isHTML := of.IsHTML isRSS := of.Name == "RSS" - var path string - - if s.Info.relativeURLs { - path = helpers.GetDottedRelativePath(targetPath) - } else if isRSS || s.Info.canonifyURLs { - url := s.PathSpec.BaseURL.String() - if !strings.HasSuffix(url, "/") { - url += "/" - } - path = url - } - pd := publisher.Descriptor{ Src: renderBuffer, TargetPath: targetPath, @@ -1625,10 +1616,10 @@ func (s *Site) renderAndWritePage(statCounter *uint64, name string, targetPath s if isRSS { // Always canonify URLs in RSS - pd.AbsURLPath = path + pd.AbsURLPath = s.absURLPath(targetPath) } else if isHTML { if s.Info.relativeURLs || s.Info.canonifyURLs { - pd.AbsURLPath = path + pd.AbsURLPath = s.absURLPath(targetPath) } if s.running() && s.Cfg.GetBool("watch") && !s.Cfg.GetBool("disableLiveReload") { diff --git a/hugolib/site_render.go b/hugolib/site_render.go index 1debcbef6..5377babef 100644 --- a/hugolib/site_render.go +++ b/hugolib/site_render.go @@ -383,7 +383,7 @@ func (s *Site) renderMainLanguageRedirect() error { if found { mainLang := s.h.multilingual.DefaultLang if s.Info.defaultContentLanguageInSubdir { - mainLangURL := s.PathSpec.AbsURL(mainLang.Lang, false) + mainLangURL := s.PathSpec.AbsURL(mainLang.Lang+"/", false) s.Log.DEBUG.Printf("Write redirect to main language %s: %s", mainLang, mainLangURL) if err := s.publishDestAlias(true, "/", mainLangURL, html, nil); err != nil { return err diff --git a/hugolib/testhelpers_test.go b/hugolib/testhelpers_test.go index 67e2caee9..eace35c97 100644 --- a/hugolib/testhelpers_test.go +++ b/hugolib/testhelpers_test.go @@ -277,9 +277,14 @@ func (s *sitesBuilder) WithSimpleConfigFile() *sitesBuilder { func (s *sitesBuilder) WithSimpleConfigFileAndBaseURL(baseURL string) *sitesBuilder { s.T.Helper() - config := fmt.Sprintf("baseURL = %q", baseURL) + return s.WithSimpleConfigFileAndSettings(map[string]interface{}{"baseURL": baseURL}) +} - config = config + commonConfigSections +func (s *sitesBuilder) WithSimpleConfigFileAndSettings(settings interface{}) *sitesBuilder { + s.T.Helper() + var buf bytes.Buffer + parser.InterfaceToConfig(settings, metadecoders.TOML, &buf) + config := buf.String() + commonConfigSections return s.WithConfigFile("toml", config) } diff --git a/transform/urlreplacers/absurlreplacer.go b/transform/urlreplacers/absurlreplacer.go index 3fef013fb..7bac716fb 100644 --- a/transform/urlreplacers/absurlreplacer.go +++ b/transform/urlreplacers/absurlreplacer.go @@ -69,6 +69,7 @@ func newPrefixState() []*prefix { return []*prefix{ {b: []byte("src="), f: checkCandidateBase}, {b: []byte("href="), f: checkCandidateBase}, + {b: []byte("url="), f: checkCandidateBase}, {b: []byte("action="), f: checkCandidateBase}, {b: []byte("srcset="), f: checkCandidateSrcset}, } diff --git a/transform/urlreplacers/absurlreplacer_test.go b/transform/urlreplacers/absurlreplacer_test.go index 3c2dbf777..8e8fdc561 100644 --- a/transform/urlreplacers/absurlreplacer_test.go +++ b/transform/urlreplacers/absurlreplacer_test.go @@ -88,8 +88,8 @@ schemaless: <img srcset='//img.jpg' src='//basic.jpg'> schemaless2: <img srcset="//img.jpg" src="//basic.jpg2> POST ` - relPathVariations = `PRE. a href="/img/small.jpg" input action="/foo.html" POST.` - relPathVariationsCorrect = `PRE. a href="../../img/small.jpg" input action="../../foo.html" POST.` + relPathVariations = `PRE. a href="/img/small.jpg" input action="/foo.html" meta url=/redirect/to/page/ POST.` + relPathVariationsCorrect = `PRE. a href="../../img/small.jpg" input action="../../foo.html" meta url=../../redirect/to/page/ POST.` testBaseURL = "http://base/" )