summaryrefslogtreecommitdiffstats
path: root/hugolib
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2019-03-30 17:08:25 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2019-04-02 10:32:47 +0200
commit92baa14fd3f45c0917c5988235cd1a0f8692f171 (patch)
tree130417443701331257f57f3d198eba2a037c079d /hugolib
parenta55640de8e3944d3b9f64b15155148a0e35cb31e (diff)
hugolib: Allow page-relative aliases
Fixes #5757
Diffstat (limited to 'hugolib')
-rw-r--r--hugolib/alias.go21
-rw-r--r--hugolib/alias_test.go21
-rw-r--r--hugolib/page__meta.go6
-rw-r--r--hugolib/site_render.go15
-rw-r--r--hugolib/site_stats_test.go2
-rw-r--r--hugolib/site_url_test.go2
6 files changed, 40 insertions, 27 deletions
diff --git a/hugolib/alias.go b/hugolib/alias.go
index 599821c0a..972f7b01c 100644
--- a/hugolib/alias.go
+++ b/hugolib/alias.go
@@ -18,6 +18,7 @@ import (
"fmt"
"html/template"
"io"
+ "path"
"path/filepath"
"runtime"
"strings"
@@ -28,8 +29,6 @@ import (
"github.com/gohugoio/hugo/publisher"
"github.com/gohugoio/hugo/resources/page"
"github.com/gohugoio/hugo/tpl"
-
- "github.com/gohugoio/hugo/helpers"
)
const (
@@ -132,13 +131,14 @@ func (a aliasHandler) targetPathAlias(src string) (string, error) {
return "", fmt.Errorf("alias \"\" is an empty string")
}
- alias := filepath.Clean(src)
- components := strings.Split(alias, helpers.FilePathSeparator)
+ alias := path.Clean(filepath.ToSlash(src))
- if !a.allowRoot && alias == helpers.FilePathSeparator {
+ if !a.allowRoot && alias == "/" {
return "", fmt.Errorf("alias \"%s\" resolves to website root directory", originalAlias)
}
+ components := strings.Split(alias, "/")
+
// Validate against directory traversal
if components[0] == ".." {
return "", fmt.Errorf("alias \"%s\" traverses outside the website root directory", originalAlias)
@@ -182,15 +182,12 @@ func (a aliasHandler) targetPathAlias(src string) (string, error) {
}
// Add the final touch
- alias = strings.TrimPrefix(alias, helpers.FilePathSeparator)
- if strings.HasSuffix(alias, helpers.FilePathSeparator) {
+ alias = strings.TrimPrefix(alias, "/")
+ if strings.HasSuffix(alias, "/") {
alias = alias + "index.html"
} else if !strings.HasSuffix(alias, ".html") {
- alias = alias + helpers.FilePathSeparator + "index.html"
- }
- if originalAlias != alias {
- a.log.INFO.Printf("Alias \"%s\" translated to \"%s\"\n", originalAlias, alias)
+ alias = alias + "/" + "index.html"
}
- return alias, nil
+ return filepath.FromSlash(alias), nil
}
diff --git a/hugolib/alias_test.go b/hugolib/alias_test.go
index f968caf23..095ae1be2 100644
--- a/hugolib/alias_test.go
+++ b/hugolib/alias_test.go
@@ -25,14 +25,14 @@ import (
const pageWithAlias = `---
title: Has Alias
-aliases: ["foo/bar/"]
+aliases: ["/foo/bar/", "rel"]
---
For some moments the old man did not reply. He stood with bowed head, buried in deep thought. But at last he spoke.
`
const pageWithAliasMultipleOutputs = `---
title: Has Alias for HTML and AMP
-aliases: ["foo/bar/"]
+aliases: ["/foo/bar/"]
outputs: ["HTML", "AMP", "JSON"]
---
For some moments the old man did not reply. He stood with bowed head, buried in deep thought. But at last he spoke.
@@ -46,16 +46,17 @@ func TestAlias(t *testing.T) {
assert := require.New(t)
b := newTestSitesBuilder(t)
- b.WithSimpleConfigFile().WithContent("page.md", pageWithAlias)
+ b.WithSimpleConfigFile().WithContent("blog/page.md", pageWithAlias)
b.CreateSites().Build(BuildCfg{})
assert.Equal(1, len(b.H.Sites))
require.Len(t, b.H.Sites[0].RegularPages(), 1)
// the real page
- b.AssertFileContent("public/page/index.html", "For some moments the old man")
- // the alias redirector
+ b.AssertFileContent("public/blog/page/index.html", "For some moments the old man")
+ // the alias redirectors
b.AssertFileContent("public/foo/bar/index.html", "<meta http-equiv=\"refresh\" content=\"0; ")
+ b.AssertFileContent("public/blog/rel/index.html", "<meta http-equiv=\"refresh\" content=\"0; ")
}
func TestAliasMultipleOutputFormats(t *testing.T) {
@@ -64,7 +65,7 @@ func TestAliasMultipleOutputFormats(t *testing.T) {
assert := require.New(t)
b := newTestSitesBuilder(t)
- b.WithSimpleConfigFile().WithContent("page.md", pageWithAliasMultipleOutputs)
+ b.WithSimpleConfigFile().WithContent("blog/page.md", pageWithAliasMultipleOutputs)
b.WithTemplates(
"_default/single.html", basicTemplate,
@@ -74,9 +75,9 @@ func TestAliasMultipleOutputFormats(t *testing.T) {
b.CreateSites().Build(BuildCfg{})
// the real pages
- b.AssertFileContent("public/page/index.html", "For some moments the old man")
- b.AssertFileContent("public/amp/page/index.html", "For some moments the old man")
- b.AssertFileContent("public/page/index.json", "For some moments the old man")
+ b.AssertFileContent("public/blog/page/index.html", "For some moments the old man")
+ b.AssertFileContent("public/amp/blog/page/index.html", "For some moments the old man")
+ b.AssertFileContent("public/blog/page/index.json", "For some moments the old man")
// the alias redirectors
b.AssertFileContent("public/foo/bar/index.html", "<meta http-equiv=\"refresh\" content=\"0; ")
@@ -135,7 +136,7 @@ func TestTargetPathHTMLRedirectAlias(t *testing.T) {
continue
}
if err == nil && path != test.expected {
- t.Errorf("Expected: \"%s\", got: \"%s\"", test.expected, path)
+ t.Errorf("Expected: %q, got: %q", test.expected, path)
}
}
}
diff --git a/hugolib/page__meta.go b/hugolib/page__meta.go
index 9f5f369b3..1e013db66 100644
--- a/hugolib/page__meta.go
+++ b/hugolib/page__meta.go
@@ -16,6 +16,7 @@ package hugolib
import (
"fmt"
"path"
+ "path/filepath"
"regexp"
"strings"
"time"
@@ -414,10 +415,11 @@ func (pm *pageMeta) setMetadata(p *pageState, frontmatter map[string]interface{}
pm.params[loki] = pm.weight
case "aliases":
pm.aliases = cast.ToStringSlice(v)
- for _, alias := range pm.aliases {
+ for i, alias := range pm.aliases {
if strings.HasPrefix(alias, "http://") || strings.HasPrefix(alias, "https://") {
- return fmt.Errorf("only relative aliases are supported, %v provided", alias)
+ return fmt.Errorf("http* aliases not supported: %q", alias)
}
+ pm.aliases[i] = filepath.ToSlash(alias)
}
pm.params[loki] = pm.aliases
case "sitemap":
diff --git a/hugolib/site_render.go b/hugolib/site_render.go
index c528e61a8..3c0897d2e 100644
--- a/hugolib/site_render.go
+++ b/hugolib/site_render.go
@@ -303,7 +303,20 @@ func (s *Site) renderAliases() error {
f := of.Format
for _, a := range p.Aliases() {
- if f.Path != "" {
+ isRelative := !strings.HasPrefix(a, "/")
+
+ if isRelative {
+ // Make alias relative, where "." will be on the
+ // same directory level as the current page.
+ // TODO(bep) ugly URLs doesn't seem to be supported in
+ // aliases, I'm not sure why not.
+ basePath := of.RelPermalink()
+ if strings.HasSuffix(basePath, "/") {
+ basePath = path.Join(basePath, "..")
+ }
+ a = path.Join(basePath, a)
+
+ } else if f.Path != "" {
// Make sure AMP and similar doesn't clash with regular aliases.
a = path.Join(f.Path, a)
}
diff --git a/hugolib/site_stats_test.go b/hugolib/site_stats_test.go
index 522b5636b..c722037b4 100644
--- a/hugolib/site_stats_test.go
+++ b/hugolib/site_stats_test.go
@@ -55,7 +55,7 @@ tags:
%s
categories:
%s
-aliases: [Ali%d]
+aliases: [/Ali%d]
---
# Doc
`
diff --git a/hugolib/site_url_test.go b/hugolib/site_url_test.go
index 10aa3bb28..9827f994b 100644
--- a/hugolib/site_url_test.go
+++ b/hugolib/site_url_test.go
@@ -26,7 +26,7 @@ import (
"github.com/stretchr/testify/require"
)
-const slugDoc1 = "---\ntitle: slug doc 1\nslug: slug-doc-1\naliases:\n - sd1/foo/\n - sd2\n - sd3/\n - sd4.html\n---\nslug doc 1 content\n"
+const slugDoc1 = "---\ntitle: slug doc 1\nslug: slug-doc-1\naliases:\n - /sd1/foo/\n - /sd2\n - /sd3/\n - /sd4.html\n---\nslug doc 1 content\n"
const slugDoc2 = `---
title: slug doc 2