hugolib, output: Handle aliases for all HTML formats

This commit is contained in:
Bjørn Erik Pedersen 2017-03-24 11:25:25 +01:00
parent 0c4701f0ef
commit 87188496fb
6 changed files with 77 additions and 22 deletions

View 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)

View 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()

View 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

View 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
}
}
}
}

View 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
}

View 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) {