diff --git a/hugolib/page_output.go b/hugolib/page_output.go index fa9a45190..cdc4a53d8 100644 --- a/hugolib/page_output.go +++ b/hugolib/page_output.go @@ -15,6 +15,7 @@ package hugolib import ( "html/template" + "strings" "sync" "github.com/spf13/hugo/output" @@ -109,3 +110,46 @@ func (p *PageOutput) Render(layout ...string) template.HTML { func (p *Page) Render(layout ...string) template.HTML { return p.mainPageOutput.Render(layout...) } + +// OutputFormats holds a list of the relevant output formats for a given resource. +type OutputFormats []*OutputFormat + +// And OutputFormat links to a representation of a resource. +type OutputFormat struct { + f output.Format + p *Page +} + +// TODO(bep) outputs consider just save this wrapper on Page. +// OutputFormats gives the output formats for this Page. +func (p *Page) OutputFormats() OutputFormats { + var o OutputFormats + for _, f := range p.outputFormats { + o = append(o, &OutputFormat{f: f, p: p}) + } + return o +} + +// Get gets a OutputFormat given its name, i.e. json, html etc. +// It returns nil if not found. +func (o OutputFormats) Get(name string) *OutputFormat { + name = strings.ToLower(name) + for _, f := range o { + if strings.ToLower(f.f.Name) == name { + return f + } + } + return nil +} + +// Permalink returns the absolute permalink to this output format. +func (o *OutputFormat) Permalink() string { + rel := o.p.createRelativePermalinkForOutputFormat(o.f) + return o.p.s.permalink(rel) +} + +// Permalink returns the relative permalink to this output format. +func (o *OutputFormat) RelPermalink() string { + rel := o.p.createRelativePermalinkForOutputFormat(o.f) + return o.p.s.PathSpec.PrependBasePath(rel) +} diff --git a/hugolib/page_paths.go b/hugolib/page_paths.go index 55d0d8cd2..00d96c05c 100644 --- a/hugolib/page_paths.go +++ b/hugolib/page_paths.go @@ -219,15 +219,23 @@ func (p *Page) createRelativePermalink() string { } // Choose the main output format. In most cases, this will be HTML. - outFormat := p.outputFormats[0] - tp, err := p.createTargetPath(outFormat) + f := p.outputFormats[0] + + return p.createRelativePermalinkForOutputFormat(f) + +} + +func (p *Page) createRelativePermalinkForOutputFormat(f output.Format) string { + tp, err := p.createTargetPath(f) if err != nil { p.s.Log.ERROR.Printf("Failed to create permalink for page %q: %s", p.FullFilePath(), err) return "" } - - tp = strings.TrimSuffix(tp, outFormat.BaseFilename()) + // For /index.json etc. we must use the full path. + if strings.HasSuffix(f.BaseFilename(), "html") { + tp = strings.TrimSuffix(tp, f.BaseFilename()) + } return p.s.PathSpec.URLizeFilename(tp) } diff --git a/hugolib/site_output_test.go b/hugolib/site_output_test.go index 3e5df6a63..12746e88b 100644 --- a/hugolib/site_output_test.go +++ b/hugolib/site_output_test.go @@ -65,7 +65,7 @@ category = "categories" pageTemplate := `--- title: "%s" -outputs: ["json"] +outputs: ["html", "json"] --- # Doc ` @@ -88,10 +88,19 @@ outputs: ["json"] require.NotNil(t, home) - require.Len(t, home.outputFormats, 1) + require.Len(t, home.outputFormats, 2) // TODO(bep) output assert template/text th.assertFileContent("public/index.json", "List JSON") + of := home.OutputFormats() + require.Len(t, of, 2) + require.Nil(t, of.Get("Hugo")) + require.NotNil(t, of.Get("json")) + json := of.Get("JSON") + require.NotNil(t, json) + require.Equal(t, "/blog/index.json", json.RelPermalink()) + require.Equal(t, "http://example.com/blog/index.json", json.Permalink()) + } diff --git a/output/outputFormat.go b/output/outputFormat.go index cc04bcbe4..392414cca 100644 --- a/output/outputFormat.go +++ b/output/outputFormat.go @@ -23,6 +23,9 @@ import ( var ( // An ordered list of built-in output formats // See https://www.ampproject.org/learn/overview/ + // TODO + // + // canonical AMPType = Format{ Name: "AMP", MediaType: media.HTMLType,