shithub: hugo

Download patch

ref: 348834d0176611fc0a08121b86c40e37644a89e3
parent: 254cd89c8e50f46bb733cc170a79e9d3089ae5a8
author: Bjørn Erik Pedersen <[email protected]>
date: Mon Mar 6 14:16:31 EST 2017

hugolib: Add a PageOutput wrapper for rendering

--- /dev/null
+++ b/hugolib/page_output.go
@@ -1,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
+}
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -1800,7 +1800,7 @@
 	// 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 @@
 	}
 
 	// 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)
 		}
--- a/hugolib/site_render.go
+++ b/hugolib/site_render.go
@@ -29,7 +29,7 @@
 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 @@
 	}
 
 	for _, page := range s.Pages {
-		pages <- page
+		for _, outputType := range page.outputTypes {
+			pages <- newPageOutput(page, outputType)
+		}
 	}
 
 	close(pages)
@@ -60,43 +62,41 @@
 	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 outputType {
+		switch p.outputType {
 
-			case output.HTMLType:
-				targetPath := p.TargetPath()
+		case output.HTMLType:
+			targetPath := p.TargetPath()
 
-				s.Log.DEBUG.Printf("Render %s to %q with layouts %q", p.Kind, targetPath, layouts)
+			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
-				}
+			if err := s.renderAndWritePage("page "+p.FullFilePath(), targetPath, p, s.appendThemeTemplates(layouts)...); 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 {
+			// 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
+			}
 		}
 
 	}
@@ -103,7 +103,7 @@
 }
 
 // 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 @@
 	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 @@
 		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 @@
 	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)...)