mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-07 20:30:36 -05:00
hugolib, output: Handle aliases for all HTML formats
This commit is contained in:
parent
0c4701f0ef
commit
87188496fb
6 changed files with 77 additions and 22 deletions
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue