diff options
Diffstat (limited to 'hugolib/page_output.go')
-rw-r--r-- | hugolib/page_output.go | 74 |
1 files changed, 70 insertions, 4 deletions
diff --git a/hugolib/page_output.go b/hugolib/page_output.go index 4739e6936..993dcb7a2 100644 --- a/hugolib/page_output.go +++ b/hugolib/page_output.go @@ -16,9 +16,12 @@ package hugolib import ( "fmt" "html/template" + "os" "strings" "sync" + "github.com/gohugoio/hugo/resource" + "github.com/gohugoio/hugo/media" "github.com/gohugoio/hugo/helpers" @@ -34,6 +37,10 @@ type PageOutput struct { paginator *Pager paginatorInit sync.Once + // Page output specific resources + resources resource.Resources + resourcesInit sync.Once + // Keep this to create URL/path variations, i.e. paginators. targetPathDescriptor targetPathDescriptor @@ -51,10 +58,7 @@ func (p *PageOutput) targetPath(addends ...string) (string, error) { func newPageOutput(p *Page, createCopy bool, f output.Format) (*PageOutput, error) { // TODO(bep) This is only needed for tests and we should get rid of it. if p.targetPathDescriptorPrototype == nil { - if err := p.initTargetPathDescriptor(); err != nil { - return nil, err - } - if err := p.initURLs(); err != nil { + if err := p.initPaths(); err != nil { return nil, err } } @@ -241,6 +245,68 @@ func (p *PageOutput) AlternativeOutputFormats() (OutputFormats, error) { return o, nil } +// deleteResource removes the resource from this PageOutput and the Page. They will +// always be of the same length, but may contain different elements. +func (p *PageOutput) deleteResource(i int) { + p.resources = append(p.resources[:i], p.resources[i+1:]...) + p.Page.Resources = append(p.Page.Resources[:i], p.Page.Resources[i+1:]...) + +} + +func (p *PageOutput) Resources() resource.Resources { + p.resourcesInit.Do(func() { + // If the current out shares the same path as the main page output, we reuse + // the resource set. For the "amp" use case, we need to clone them with new + // base folder. + ff := p.outputFormats[0] + if p.outputFormat.Path == ff.Path { + p.resources = p.Page.Resources + return + } + + // Clone it with new base. + resources := make(resource.Resources, len(p.Page.Resources)) + + for i, r := range p.Page.Resources { + if c, ok := r.(resource.Cloner); ok { + // Clone the same resource with a new target. + resources[i] = c.WithNewBase(p.outputFormat.Path) + } else { + resources[i] = r + } + } + + p.resources = resources + }) + + return p.resources +} + +func (p *PageOutput) renderResources() error { + + for i, r := range p.Resources() { + src, ok := r.(resource.Source) + if !ok { + // Pages gets rendered with the owning page. + continue + } + + if err := src.Publish(); err != nil { + if os.IsNotExist(err) { + // The resource has been deleted from the file system. + // This should be extremely rare, but can happen on live reload in server + // mode when the same resource is member of different page bundles. + p.deleteResource(i) + } else { + p.s.Log.ERROR.Printf("Failed to publish %q for page %q: %s", src.AbsSourceFilename(), p.pathOrTitle(), err) + } + } else { + p.s.PathSpec.ProcessingStats.Incr(&p.s.PathSpec.ProcessingStats.Files) + } + } + return nil +} + // AlternativeOutputFormats is only available on the top level rendering // entry point, and not inside range loops on the Page collections. // This method is just here to inform users of that restriction. |