hugolib, output: Handle aliases for all HTML formats
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 24 Mar 2017 10:25:25 +0000 (11:25 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 27 Mar 2017 13:43:56 +0000 (15:43 +0200)
hugolib/alias.go
hugolib/alias_test.go
hugolib/page_output.go
hugolib/site_render.go
output/outputFormat.go
output/outputFormat_test.go

index 7120e608616d43508336f9d34dc9635bd5812a07..d5eb35777dfbf2258a3ad4a033ff8bc41a945ea6 100644 (file)
@@ -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)
index f5e6d8d1fa3f1322c44bd40a6218eea0ef76410e..68ec8f07f38c6964a36d059a460f11435526eb35 100644 (file)
@@ -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()
 
index ec662bf231868c618a0c086f503e0f26d13bb1f4..2416e22b5f22607f621e594bec551ebad6d880af 100644 (file)
@@ -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
index 2da02ef539e71841104769e870288eace8a7c3c3..d16adcfafb85e858520f045ad8d443524ddcf5bf 100644 (file)
@@ -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
+                               }
                        }
                }
        }
index c50d74f3fe8e070d99e581db16e83eb70510a3de..2ef5fb62bc7ff71364b6a76db05f570a4723b9bd 100644 (file)
@@ -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
 }
index a76c50aee8e977da032d13a3dbc7a09980b3757a..5ef57f975462abfbe4b98f616bd2484f6a540ef4 100644 (file)
@@ -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) {