hugolib: Add a PageOutput wrapper for rendering
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 6 Mar 2017 18:16:31 +0000 (19:16 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 27 Mar 2017 13:43:56 +0000 (15:43 +0200)
hugolib/page_output.go [new file with mode: 0644]
hugolib/site.go
hugolib/site_render.go

diff --git a/hugolib/page_output.go b/hugolib/page_output.go
new file mode 100644 (file)
index 0000000..79b7ead
--- /dev/null
@@ -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
+}
index 08bfcf4d6d6ddf56e6fa4eb1e807404634df7a04..784510fdb1a33ed98145f86af052a5424317d47e 100644 (file)
@@ -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)
                }
index 7da4e433fbd2bbe9af30bbc04cbdbcfcbf5dee0a..51886d34ba03d0b093b3ff4ea7d773c4215a8c46 100644 (file)
@@ -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,50 +62,48 @@ 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
-
-                       if len(p.layoutsCalculated) > 0 {
-                               // TODO(bep) output
-                               layouts = p.layoutsCalculated
-                       } else {
-                               layouts = s.layoutHandler.For(p.layoutIdentifier, "", outputType)
-                       }
+               // TODO(bep) output check if some of the interface{} methods below checks for *Page
+               var layouts []string
 
-                       switch outputType {
+               if len(p.layoutsCalculated) > 0 {
+                       // TODO(bep) output
+                       layouts = p.layoutsCalculated
+               } else {
+                       layouts = s.layoutHandler.For(p.layoutIdentifier, "", p.outputType)
+               }
 
-                       case output.HTMLType:
-                               targetPath := p.TargetPath()
+               switch p.outputType {
 
-                               s.Log.DEBUG.Printf("Render %s to %q with layouts %q", p.Kind, targetPath, layouts)
+               case output.HTMLType:
+                       targetPath := p.TargetPath()
 
-                               if err := s.renderAndWritePage("page "+p.FullFilePath(), targetPath, p, s.appendThemeTemplates(layouts)...); err != nil {
-                                       results <- err
-                               }
+                       s.Log.DEBUG.Printf("Render %s to %q with layouts %q", p.Kind, targetPath, layouts)
 
-                               // 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
-                                       }
-                               }
+                       if err := s.renderAndWritePage("page "+p.FullFilePath(), targetPath, p, s.appendThemeTemplates(layouts)...); err != nil {
+                               results <- err
+                       }
 
-                       case output.RSSType:
-                               if err := s.renderRSS(p); 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
                                }
                        }
+
+               case output.RSSType:
+                       if err := s.renderRSS(p); err != nil {
+                               results <- err
+                       }
                }
 
        }
 }
 
 // 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)...)