hugo

Unnamed repository; edit this file 'description' to name the repository.

git clone git://git.shimmy1996.com/hugo.git
commit 87188496fbb68c39567ec3ee3a55a9305a13e48b
parent 0c4701f0effbf651891979b925073f6fc5d26a82
Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Date:   Fri, 24 Mar 2017 11:25:25 +0100

hugolib, output: Handle aliases for all HTML formats

Diffstat:
Mhugolib/alias.go | 12------------
Mhugolib/alias_test.go | 34++++++++++++++++++++++++++++++++++
Mhugolib/page_output.go | 16++++++++++------
Mhugolib/site_render.go | 20++++++++++++++++----
Moutput/outputFormat.go | 6++++++
Moutput/outputFormat_test.go | 11+++++++++++
6 files changed, 77 insertions(+), 22 deletions(-)
diff --git a/hugolib/alias.go b/hugolib/alias.go
@@ -88,18 +88,6 @@ func (s *Site) publishDestAlias(allowRoot bool, path, permalink string, p *Page)
 
 	isXHTML := strings.HasSuffix(path, ".xhtml")
 
-	if s.Info.relativeURLs {
-		// convert `permalink` into URI relative to location of `path`
-		baseURL := helpers.SanitizeURLKeepTrailingSlash(s.Cfg.GetString("baseURL"))
-		if strings.HasPrefix(permalink, baseURL) {
-			permalink = "/" + strings.TrimPrefix(permalink, baseURL)
-		}
-		permalink, err = helpers.GetRelativePath(permalink, path)
-		if err != nil {
-			s.Log.ERROR.Println("Failed to make a RelativeURL alias:", path, "redirecting to", permalink)
-		}
-		permalink = filepath.ToSlash(permalink)
-	}
 	s.Log.DEBUG.Println("creating alias:", path, "redirecting to", permalink)
 
 	targetPath, err := handler.targetPathAlias(path)
diff --git a/hugolib/alias_test.go b/hugolib/alias_test.go
@@ -29,6 +29,14 @@ aliases: ["foo/bar/"]
 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/"]
+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.
+`
+
 const basicTemplate = "<html><body>{{.Content}}</body></html>"
 const aliasTemplate = "<html><body>ALIASTEMPLATE</body></html>"
 
@@ -51,6 +59,32 @@ func TestAlias(t *testing.T) {
 	th.assertFileContent(filepath.Join("public", "foo", "bar", "index.html"), "<meta http-equiv=\"refresh\" content=\"0; ")
 }
 
+func TestAliasMultipleOutputFormats(t *testing.T) {
+	t.Parallel()
+
+	var (
+		cfg, fs = newTestCfg()
+		th      = testHelper{cfg, fs, t}
+	)
+
+	writeSource(t, fs, filepath.Join("content", "page.md"), pageWithAliasMultipleOutputs)
+	writeSource(t, fs, filepath.Join("layouts", "_default", "single.html"), basicTemplate)
+	writeSource(t, fs, filepath.Join("layouts", "_default", "single.amp.html"), basicTemplate)
+	writeSource(t, fs, filepath.Join("layouts", "_default", "single.json"), basicTemplate)
+
+	buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{})
+
+	// the real pages
+	th.assertFileContent(filepath.Join("public", "page", "index.html"), "For some moments the old man")
+	th.assertFileContent(filepath.Join("public", "amp", "page", "index.html"), "For some moments the old man")
+	th.assertFileContent(filepath.Join("public", "page", "index.json"), "For some moments the old man")
+
+	// the alias redirectors
+	th.assertFileContent(filepath.Join("public", "foo", "bar", "index.html"), "<meta http-equiv=\"refresh\" content=\"0; ")
+	th.assertFileContent(filepath.Join("public", "foo", "bar", "amp", "index.html"), "<meta http-equiv=\"refresh\" content=\"0; ")
+	require.False(t, destinationExists(th.Fs, filepath.Join("public", "foo", "bar", "index.json")))
+}
+
 func TestAliasTemplate(t *testing.T) {
 	t.Parallel()
 
diff --git a/hugolib/page_output.go b/hugolib/page_output.go
@@ -152,17 +152,21 @@ func (o OutputFormat) MediaType() media.Type {
 // OutputFormats gives the output formats for this Page.
 func (p *Page) OutputFormats() OutputFormats {
 	var o OutputFormats
-	isCanonical := len(p.outputFormats) == 1
 	for _, f := range p.outputFormats {
-		rel := f.Rel
-		if isCanonical {
-			rel = "canonical"
-		}
-		o = append(o, &OutputFormat{Rel: rel, f: f, p: p})
+		o = append(o, newOutputFormat(p, f))
 	}
 	return o
 }
 
+func newOutputFormat(p *Page, f output.Format) *OutputFormat {
+	rel := f.Rel
+	isCanonical := len(p.outputFormats) == 1
+	if isCanonical {
+		rel = "canonical"
+	}
+	return &OutputFormat{Rel: rel, f: f, p: p}
+}
+
 // OutputFormats gives the alternative output formats for this PageOutput.
 func (p *PageOutput) AlternativeOutputFormats() (OutputFormats, error) {
 	var o OutputFormats
diff --git a/hugolib/site_render.go b/hugolib/site_render.go
@@ -305,11 +305,23 @@ func (s *Site) renderAliases() error {
 			continue
 		}
 
-		plink := p.Permalink()
+		for _, f := range p.outputFormats {
+			if !f.IsHTML {
+				continue
+			}
 
-		for _, a := range p.Aliases {
-			if err := s.writeDestAlias(a, plink, p); err != nil {
-				return err
+			o := newOutputFormat(p, f)
+			plink := o.Permalink()
+
+			for _, a := range p.Aliases {
+				if f.Path != "" {
+					// Make sure AMP and similar doesn't clash with regular aliases.
+					a = path.Join(a, f.Path)
+				}
+
+				if err := s.writeDestAlias(a, plink, p); err != nil {
+					return err
+				}
 			}
 		}
 	}
diff --git a/output/outputFormat.go b/output/outputFormat.go
@@ -29,6 +29,7 @@ var (
 		BaseName:  "index",
 		Path:      "amp",
 		Rel:       "amphtml",
+		IsHTML:    true,
 	}
 
 	CalendarType = Format{
@@ -52,6 +53,7 @@ var (
 		MediaType: media.HTMLType,
 		BaseName:  "index",
 		Rel:       "canonical",
+		IsHTML:    true,
 	}
 
 	JSONType = Format{
@@ -113,6 +115,10 @@ type Format struct {
 	// as template parser.
 	IsPlainText bool
 
+	// IsHTML returns whether this format is int the HTML family. This includes
+	// HTML, AMP etc. This is used to decide when to create alias redirects etc.
+	IsHTML bool
+
 	// Enable to ignore the global uglyURLs setting.
 	NoUgly bool
 }
diff --git a/output/outputFormat_test.go b/output/outputFormat_test.go
@@ -26,18 +26,29 @@ func TestDefaultTypes(t *testing.T) {
 	require.Equal(t, "webcal://", CalendarType.Protocol)
 	require.Empty(t, CalendarType.Path)
 	require.True(t, CalendarType.IsPlainText)
+	require.False(t, CalendarType.IsHTML)
 
 	require.Equal(t, "HTML", HTMLType.Name)
 	require.Equal(t, media.HTMLType, HTMLType.MediaType)
 	require.Empty(t, HTMLType.Path)
 	require.Empty(t, HTMLType.Protocol) // Will inherit the BaseURL protocol.
 	require.False(t, HTMLType.IsPlainText)
+	require.True(t, HTMLType.IsHTML)
+
+	require.Equal(t, "AMP", AMPType.Name)
+	require.Equal(t, media.HTMLType, AMPType.MediaType)
+	require.Equal(t, "amp", AMPType.Path)
+	require.Empty(t, AMPType.Protocol) // Will inherit the BaseURL protocol.
+	require.False(t, AMPType.IsPlainText)
+	require.True(t, AMPType.IsHTML)
 
 	require.Equal(t, "RSS", RSSType.Name)
 	require.Equal(t, media.RSSType, RSSType.MediaType)
 	require.Empty(t, RSSType.Path)
 	require.False(t, RSSType.IsPlainText)
 	require.True(t, RSSType.NoUgly)
+	require.False(t, CalendarType.IsHTML)
+
 }
 
 func TestGetType(t *testing.T) {