Skip to content

Commit

Permalink
Make the RenderString content provider fix more general
Browse files Browse the repository at this point in the history
Updates #9383
  • Loading branch information
bep committed Jan 27, 2022
1 parent 85d31f7 commit f22c4ab
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 167 deletions.
102 changes: 4 additions & 98 deletions hugolib/page.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,12 @@ package hugolib
import (
"bytes"
"fmt"
"html/template"
"os"
"path"
"path/filepath"
"sort"
"strings"

"github.com/mitchellh/mapstructure"

"github.com/gohugoio/hugo/identity"

"github.com/gohugoio/hugo/markup/converter"
Expand All @@ -47,7 +44,6 @@ import (

"github.com/gohugoio/hugo/media"
"github.com/gohugoio/hugo/source"
"github.com/spf13/cast"

"github.com/gohugoio/hugo/common/collections"
"github.com/gohugoio/hugo/common/text"
Expand Down Expand Up @@ -593,106 +589,13 @@ var defaultRenderStringOpts = renderStringOpts{
Markup: "", // Will inherit the page's value when not set.
}

func (p *pageState) RenderString(args ...interface{}) (template.HTML, error) {
if len(args) < 1 || len(args) > 2 {
return "", errors.New("want 1 or 2 arguments")
}

var s string
opts := defaultRenderStringOpts
sidx := 1

if len(args) == 1 {
sidx = 0
} else {
m, ok := args[0].(map[string]interface{})
if !ok {
return "", errors.New("first argument must be a map")
}

if err := mapstructure.WeakDecode(m, &opts); err != nil {
return "", errors.WithMessage(err, "failed to decode options")
}
}

var err error
s, err = cast.ToStringE(args[sidx])
if err != nil {
return "", err
}

if err = p.pageOutput.initRenderHooks(); err != nil {
return "", err
}

conv := p.getContentConverter()
if opts.Markup != "" && opts.Markup != p.m.markup {
var err error
// TODO(bep) consider cache
conv, err = p.m.newContentConverter(p, opts.Markup, nil)
if err != nil {
return "", p.wrapError(err)
}
}

var cp *pageContentOutput

// If the current content provider is not yet initialized, do so now.
if lcp, ok := p.pageOutput.ContentProvider.(*page.LazyContentProvider); ok {
c := lcp.Init()
if pco, ok := c.(*pageContentOutput); ok {
cp = pco
}
} else {
cp = p.pageOutput.cp
}

c, err := cp.renderContentWithConverter(conv, []byte(s), false)
if err != nil {
return "", p.wrapError(err)
}

b := c.Bytes()

if opts.Display == "inline" {
// We may have to rethink this in the future when we get other
// renderers.
b = p.s.ContentSpec.TrimShortHTML(b)
}

return template.HTML(string(b)), nil
}

func (p *pageState) addDependency(dep identity.Provider) {
if !p.s.running() || p.pageOutput.cp == nil {
return
}
p.pageOutput.cp.dependencyTracker.Add(dep)
}

func (p *pageState) RenderWithTemplateInfo(info tpl.Info, layout ...string) (template.HTML, error) {
p.addDependency(info)
return p.Render(layout...)
}

func (p *pageState) Render(layout ...string) (template.HTML, error) {
templ, found, err := p.resolveTemplate(layout...)
if err != nil {
return "", p.wrapError(err)
}

if !found {
return "", nil
}

p.addDependency(templ.(tpl.Info))
res, err := executeToString(p.s.Tmpl(), templ, p)
if err != nil {
return "", p.wrapError(errors.Wrapf(err, "failed to execute template %q v", layout))
}
return template.HTML(res), nil
}

// wrapError adds some more context to the given error if possible/needed
func (p *pageState) wrapError(err error) error {
if _, ok := err.(*herrors.ErrorWithFileContext); ok {
Expand Down Expand Up @@ -993,13 +896,16 @@ func (p *pageState) shiftToOutputFormat(isRenderingSite bool, idx int) error {
if lcp, ok := (p.pageOutput.ContentProvider.(*page.LazyContentProvider)); ok {
lcp.Reset()
} else {
p.pageOutput.ContentProvider = page.NewLazyContentProvider(func() (page.ContentProvider, error) {
lcp = page.NewLazyContentProvider(func() (page.OutputFormatContentProvider, error) {
cp, err := newPageContentOutput(p, p.pageOutput)
if err != nil {
return nil, err
}
return cp, nil
})
p.pageOutput.ContentProvider = lcp
p.pageOutput.TableOfContentsProvider = lcp
p.pageOutput.PageRenderProvider = lcp
}
}

Expand Down
1 change: 0 additions & 1 deletion hugolib/page__common.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ type pageCommon struct {
maps.Scratcher
navigation.PageMenusProvider
page.AuthorProvider
page.PageRenderProvider
page.AlternativeOutputFormatsProvider
page.ChildCareProvider
page.FileProvider
Expand Down
1 change: 0 additions & 1 deletion hugolib/page__new.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ func newPageBase(metaProvider *pageMeta) (*pageState, error) {
ps.Eqer = ps
ps.TranslationKeyProvider = ps
ps.ShortcodeInfoProvider = ps
ps.PageRenderProvider = ps
ps.AlternativeOutputFormatsProvider = ps

return ps, nil
Expand Down
60 changes: 3 additions & 57 deletions hugolib/page__output.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
package hugolib

import (
"github.com/gohugoio/hugo/markup/converter"
"github.com/gohugoio/hugo/output"
"github.com/gohugoio/hugo/resources/page"
"github.com/gohugoio/hugo/resources/resource"
Expand Down Expand Up @@ -59,6 +58,7 @@ func newPageOutput(
pagePerOutputProviders: providers,
ContentProvider: page.NopPage,
TableOfContentsProvider: page.NopPage,
PageRenderProvider: page.NopPage,
render: render,
paginator: pag,
}
Expand All @@ -84,73 +84,19 @@ type pageOutput struct {
pagePerOutputProviders
page.ContentProvider
page.TableOfContentsProvider
page.PageRenderProvider

// May be nil.
cp *pageContentOutput
}

func (o *pageOutput) initRenderHooks() error {
if o.cp == nil {
return nil
}

var initErr error

o.cp.renderHooks.init.Do(func() {
ps := o.cp.p

c := ps.getContentConverter()
if c == nil || !c.Supports(converter.FeatureRenderHooks) {
return
}

h, err := ps.createRenderHooks(o.f)
if err != nil {
initErr = err
return
}
o.cp.renderHooks.hooks = h

if !o.cp.renderHooksHaveVariants || h.IsZero() {
// Check if there is a different render hooks template
// for any of the other page output formats.
// If not, we can reuse this.
for _, po := range ps.pageOutputs {
if po.f.Name != o.f.Name {
h2, err := ps.createRenderHooks(po.f)
if err != nil {
initErr = err
return
}

if h2.IsZero() {
continue
}

if o.cp.renderHooks.hooks.IsZero() {
o.cp.renderHooks.hooks = h2
}

o.cp.renderHooksHaveVariants = !h2.Eq(o.cp.renderHooks.hooks)

if o.cp.renderHooksHaveVariants {
break
}

}
}
}
})

return initErr
}

func (p *pageOutput) initContentProvider(cp *pageContentOutput) {
if cp == nil {
return
}
p.ContentProvider = cp
p.TableOfContentsProvider = cp
p.PageRenderProvider = cp
p.cp = cp
}

Expand Down
Loading

0 comments on commit f22c4ab

Please sign in to comment.