From 348834d0176611fc0a08121b86c40e37644a89e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Mon, 6 Mar 2017 19:16:31 +0100 Subject: [PATCH] hugolib: Add a PageOutput wrapper for rendering --- hugolib/page_output.go | 40 +++++++++++++++++++++++++ hugolib/site.go | 4 +-- hugolib/site_render.go | 68 +++++++++++++++++++++--------------------- 3 files changed, 76 insertions(+), 36 deletions(-) create mode 100644 hugolib/page_output.go diff --git a/hugolib/page_output.go b/hugolib/page_output.go new file mode 100644 index 000000000..79b7ead9a --- /dev/null +++ b/hugolib/page_output.go @@ -0,0 +1,40 @@ +// Copyright 2017 The Hugo Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hugolib + +import ( + "github.com/spf13/hugo/output" +) + +// PageOutput represents one of potentially many output formats of a given +// Page. +type PageOutput struct { + *Page + + outputType output.Type +} + +func newPageOutput(p *Page, outputType output.Type) *PageOutput { + // TODO(bep) output avoid copy of first? + p = p.copy() + return &PageOutput{Page: p, outputType: outputType} +} + +// copy creates a copy of this PageOutput with the lazy sync.Once vars reset +// so they will be evaluated again, for word count calculations etc. +func (p *PageOutput) copy() *PageOutput { + c := *p + c.Page = p.Page.copy() + return &c +} diff --git a/hugolib/site.go b/hugolib/site.go index 08bfcf4d6..784510fdb 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -1800,7 +1800,7 @@ func (s *Site) renderAndWritePage(name string, dest string, d interface{}, layou // Note: this is not a pointer, as we may mutate the state below. w := s.w - if p, ok := d.(*Page); ok && p.IsPage() && path.Ext(p.URLPath.URL) != "" { + if p, ok := d.(*PageOutput); ok && p.IsPage() && path.Ext(p.URLPath.URL) != "" { // user has explicitly set a URL with extension for this page // make sure it sticks even if "ugly URLs" are turned off. w.uglyURLs = true @@ -1817,7 +1817,7 @@ func (s *Site) renderAndWritePage(name string, dest string, d interface{}, layou } // For performance reasons we only inject the Hugo generator tag on the home page. - if n, ok := d.(*Page); ok && n.IsHome() { + if n, ok := d.(*PageOutput); ok && n.IsHome() { if !s.Cfg.GetBool("disableHugoGeneratorInject") { transformLinks = append(transformLinks, transform.HugoGeneratorInject) } diff --git a/hugolib/site_render.go b/hugolib/site_render.go index 7da4e433f..51886d34b 100644 --- a/hugolib/site_render.go +++ b/hugolib/site_render.go @@ -29,7 +29,7 @@ import ( func (s *Site) renderPages() error { results := make(chan error) - pages := make(chan *Page) + pages := make(chan *PageOutput) errs := make(chan error) go errorCollator(results, errs) @@ -44,7 +44,9 @@ func (s *Site) renderPages() error { } for _, page := range s.Pages { - pages <- page + for _, outputType := range page.outputTypes { + pages <- newPageOutput(page, outputType) + } } close(pages) @@ -60,42 +62,40 @@ func (s *Site) renderPages() error { return nil } -func pageRenderer(s *Site, pages <-chan *Page, results chan<- error, wg *sync.WaitGroup) { +func pageRenderer(s *Site, pages <-chan *PageOutput, results chan<- error, wg *sync.WaitGroup) { defer wg.Done() for p := range pages { - // TODO(bep) output - for _, outputType := range p.outputTypes { - var layouts []string + // TODO(bep) output check if some of the interface{} methods below checks for *Page + var layouts []string - if len(p.layoutsCalculated) > 0 { - // TODO(bep) output - layouts = p.layoutsCalculated - } else { - layouts = s.layoutHandler.For(p.layoutIdentifier, "", outputType) + if len(p.layoutsCalculated) > 0 { + // TODO(bep) output + layouts = p.layoutsCalculated + } else { + layouts = s.layoutHandler.For(p.layoutIdentifier, "", p.outputType) + } + + switch p.outputType { + + case output.HTMLType: + targetPath := p.TargetPath() + + s.Log.DEBUG.Printf("Render %s to %q with layouts %q", p.Kind, targetPath, layouts) + + if err := s.renderAndWritePage("page "+p.FullFilePath(), targetPath, p, s.appendThemeTemplates(layouts)...); err != nil { + results <- err } - switch outputType { - - case output.HTMLType: - targetPath := p.TargetPath() - - s.Log.DEBUG.Printf("Render %s to %q with layouts %q", p.Kind, targetPath, layouts) - - if err := s.renderAndWritePage("page "+p.FullFilePath(), targetPath, p, s.appendThemeTemplates(layouts)...); err != nil { + // Taxonomy terms have no page set to paginate, so skip that for now. + if p.IsNode() && p.Kind != KindTaxonomyTerm { + if err := s.renderPaginator(p); err != nil { results <- err } + } - // Taxonomy terms have no page set to paginate, so skip that for now. - if p.IsNode() && p.Kind != KindTaxonomyTerm { - if err := s.renderPaginator(p); err != nil { - results <- err - } - } - - case output.RSSType: - if err := s.renderRSS(p); err != nil { - results <- err - } + case output.RSSType: + if err := s.renderRSS(p); err != nil { + results <- err } } @@ -103,7 +103,7 @@ func pageRenderer(s *Site, pages <-chan *Page, results chan<- error, wg *sync.Wa } // renderPaginator must be run after the owning Page has been rendered. -func (s *Site) renderPaginator(p *Page) error { +func (s *Site) renderPaginator(p *PageOutput) error { if p.paginator != nil { s.Log.DEBUG.Printf("Render paginator for page %q", p.Path()) paginatePath := s.Cfg.GetString("paginatePath") @@ -146,7 +146,7 @@ func (s *Site) renderPaginator(p *Page) error { return nil } -func (s *Site) renderRSS(p *Page) error { +func (s *Site) renderRSS(p *PageOutput) error { if !s.isEnabled(kindRSS) { return nil @@ -163,7 +163,7 @@ func (s *Site) renderRSS(p *Page) error { return nil } - rssPage := p.copy() + rssPage := p // p.copy() TODO(bep) output rssPage.Kind = kindRSS // TODO(bep) we zero the date here to get the number of diffs down in @@ -182,7 +182,7 @@ func (s *Site) renderRSS(p *Page) error { rssURI := s.Language.GetString("rssURI") rssPath := path.Join(append(rssPage.sections, rssURI)...) - s.setPageURLs(rssPage, rssPath) + s.setPageURLs(rssPage.Page, rssPath) return s.renderAndWriteXML(rssPage.Title, rssPage.addLangFilepathPrefix(rssPath), rssPage, s.appendThemeTemplates(layouts)...)