From 2ee44cf787e3440c4c9968d0df1c7d9f30391c1e Mon Sep 17 00:00:00 2001 From: Oliver Steele Date: Wed, 16 Aug 2017 15:50:31 -0400 Subject: [PATCH] Recompute excerpt after rendering --- collection/collection.go | 5 +++++ commands/benchmark.go | 2 +- commands/build.go | 2 +- example/collections.html | 14 +++++++------ example/index.md | 2 +- pages/page.go | 44 ++++++++++++++++++++-------------------- site/build.go | 15 -------------- site/rebuild.go | 2 +- site/render.go | 29 +++++++++++--------------- site/write.go | 19 ++++++++++++++++- 10 files changed, 69 insertions(+), 65 deletions(-) diff --git a/collection/collection.go b/collection/collection.go index fb634fc..4e391d5 100644 --- a/collection/collection.go +++ b/collection/collection.go @@ -1,6 +1,7 @@ package collection import ( + "fmt" "path/filepath" "github.com/osteele/gojekyll/config" @@ -39,6 +40,10 @@ func New(s Site, name string, metadata map[string]interface{}) *Collection { } } +func (c *Collection) String() string { + return fmt.Sprintf("%T{Name=%q}", c, c.Name) +} + // AbsDir returns the absolute path to the collection directory. func (c *Collection) AbsDir() string { return filepath.Join(c.cfg.SourceDir(), c.PathPrefix()) diff --git a/commands/benchmark.go b/commands/benchmark.go index f196ca2..4005ca1 100644 --- a/commands/benchmark.go +++ b/commands/benchmark.go @@ -21,7 +21,7 @@ func benchmarkCommand() (err error) { if err != nil { return err } - _, err = site.Build() + _, err = site.Write() if err != nil { return err } diff --git a/commands/build.go b/commands/build.go index 4ac4176..4d9ef8f 100644 --- a/commands/build.go +++ b/commands/build.go @@ -22,7 +22,7 @@ func buildCommand(site *site.Site) error { logger.path("Destination:", site.DestDir()) logger.label("Generating...", "") - count, err := site.Build() + count, err := site.Write() switch { case err == nil: elapsed := time.Since(commandStartTime) diff --git a/example/collections.html b/example/collections.html index 7185ce4..180c0ad 100644 --- a/example/collections.html +++ b/example/collections.html @@ -14,18 +14,20 @@ {% for p in c.docs %}
  • {{ p.path }} - - - - - + {% for k in p %} + + + + + {% endfor %} +
    properties{% for k in p %}{{k}} {% endfor %}
    {{k}}
    {{p[k]}}
  • {% endfor %} diff --git a/example/index.md b/example/index.md index 02d3b90..73f8fe5 100644 --- a/example/index.md +++ b/example/index.md @@ -15,7 +15,7 @@ variable: page variable ## Tests * [Archive]({% link archive.md %}) -* [Collections]({% link collections.md %}) +* [Collections]({% link collections.html %}) * [Markdown]({% link markdown.md %}) * [Pages]({% link pages.md %}) * [Plugins]({% link plugins.md %}) diff --git a/pages/page.go b/pages/page.go index 668d588..baa711d 100644 --- a/pages/page.go +++ b/pages/page.go @@ -6,6 +6,7 @@ import ( "io" "io/ioutil" "path" + "strings" "sync" "time" @@ -200,19 +201,14 @@ func (p *page) Render() error { return p.contentError } -func (p *page) Excerpt() interface{} { - p.RLock() - defer p.RUnlock() - if exc, ok := p.frontMatter["excerpt"]; ok { - return exc - } - if p.rendered { - return p.excerpt - } - return p.extractExcerpt() +func (p *page) SetContent(content string) { + p.Lock() + defer p.Unlock() + p.content = content + p.contentError = nil } -func (p *page) computeContent() (cn string, ex interface{}, err error) { +func (p *page) computeContent() (cn string, ex string, err error) { pl := p.site.RenderingPipeline() buf := new(bytes.Buffer) err = pl.Render(buf, p.raw, p.TemplateContext(), p.filename, p.firstLine) @@ -221,14 +217,25 @@ func (p *page) computeContent() (cn string, ex interface{}, err error) { } cn = buf.String() ex = cn - exb := p.extractExcerpt() - if !bytes.Equal(exb, p.raw) { - buf.Reset() - ex, err = pl.RenderTemplate(exb, p.TemplateContext(), p.filename, p.firstLine) + pos := strings.Index(ex, p.site.Config().ExcerptSeparator) + if pos >= 0 { + ex = ex[:pos] } return } +func (p *page) Excerpt() interface{} { + if exc, ok := p.frontMatter["excerpt"]; ok { + return exc + } + p.RLock() + defer p.RUnlock() + if p.rendered { + return p.excerpt + } + return p.extractExcerpt() +} + func (p *page) extractExcerpt() []byte { raw := p.raw pos := bytes.Index(raw, []byte(p.site.Config().ExcerptSeparator)) @@ -237,10 +244,3 @@ func (p *page) extractExcerpt() []byte { } return raw } - -func (p *page) SetContent(content string) { - p.Lock() - defer p.Unlock() - p.content = content - p.contentError = nil -} diff --git a/site/build.go b/site/build.go index a4457f1..2f717d4 100644 --- a/site/build.go +++ b/site/build.go @@ -38,21 +38,6 @@ func (s *Site) Clean() error { return utils.RemoveEmptyDirectories(s.DestDir()) } -// Build cleans the destination and create files in it. -// This sets TZ from the site config. -func (s *Site) Build() (int, error) { - if err := s.setTimeZone(); err != nil { - return 0, err - } - if err := s.ensureRendered(); err != nil { - return 0, err - } - if err := s.Clean(); err != nil { - return 0, err - } - return s.WriteFiles() -} - func (s *Site) setTimeZone() error { if tz := s.config.Timezone; tz != "" { if _, err := time.LoadLocation(tz); err != nil { diff --git a/site/rebuild.go b/site/rebuild.go index d4716dc..bb09bbd 100644 --- a/site/rebuild.go +++ b/site/rebuild.go @@ -68,7 +68,7 @@ func (s *Site) rebuild(paths []string) (r *Site, n int, err error) { if err != nil { return } - n, err = r.Build() + n, err = r.Write() return } r = s diff --git a/site/render.go b/site/render.go index 52eb589..f9073cd 100644 --- a/site/render.go +++ b/site/render.go @@ -6,12 +6,9 @@ import ( "github.com/osteele/gojekyll/collection" ) -// Render renders the site's pages. -func (s *Site) Render() error { - cols := make([]*collection.Collection, 0, len(s.Collections)) - copy(cols, s.Collections) - sort.Sort(postsCollectionLast(cols)) - for _, c := range cols { +// render renders the site's pages. +func (s *Site) render() error { + for _, c := range s.sortedCollections() { if err := c.Render(); err != nil { return err } @@ -30,7 +27,7 @@ func (s *Site) ensureRendered() (err error) { if err != nil { return } - err = s.Render() + err = s.render() if err != nil { return } @@ -38,12 +35,16 @@ func (s *Site) ensureRendered() (err error) { return } -type postsCollectionLast []*collection.Collection - -func (d postsCollectionLast) Len() int { - return len([]*collection.Collection(d)) +// returns a slice of collections, sorted by name but with _posts last. +func (s *Site) sortedCollections() []*collection.Collection { + cols := make([]*collection.Collection, len(s.Collections)) + copy(cols, s.Collections) + sort.Slice(cols, postsCollectionLast(cols).Less) + return cols } +type postsCollectionLast []*collection.Collection + func (d postsCollectionLast) Less(i, j int) bool { array := []*collection.Collection(d) a, b := array[i], array[j] @@ -56,9 +57,3 @@ func (d postsCollectionLast) Less(i, j int) bool { return a.Name < b.Name } } - -func (d postsCollectionLast) Swap(i, j int) { - array := []*collection.Collection(d) - a, b := array[i], array[j] - array[i], array[j] = b, a -} diff --git a/site/write.go b/site/write.go index c5683a2..073d25d 100644 --- a/site/write.go +++ b/site/write.go @@ -12,6 +12,21 @@ import ( "github.com/osteele/gojekyll/utils" ) +// Write cleans the destination and writes files into it. +// It sets TZ from the site config. +func (s *Site) Write() (int, error) { + if err := s.setTimeZone(); err != nil { + return 0, err + } + if err := s.ensureRendered(); err != nil { + return 0, err + } + if err := s.Clean(); err != nil { + return 0, err + } + return s.WriteFiles() +} + // WriteFiles writes output files. func (s *Site) WriteFiles() (count int, err error) { errs := make(chan error) @@ -76,7 +91,9 @@ func (s *Site) WriteDocument(w io.Writer, d pages.Document) error { } } -// WritePage writes the rendered page. +// WritePage writes the rendered page. It is called as part of site.Write, +// but also, in an incremental build, to write a single page – therefore it +// also ensures that all pages have been rendered before writing this one. func (s *Site) WritePage(w io.Writer, p pages.Page) error { if err := s.ensureRendered(); err != nil { return err