diff --git a/hugolib/content_map_page.go b/hugolib/content_map_page.go index e7661bb81cd..bf0e52dfeb9 100644 --- a/hugolib/content_map_page.go +++ b/hugolib/content_map_page.go @@ -174,7 +174,7 @@ func (m *pageMap) newPageFromContentNode(n *contentNode, parentBucket *pagesMapB return nil, err } - ps.init.Add(func() (interface{}, error) { + ps.init.Add(func(ctx context.Context) (interface{}, error) { pp, err := newPagePaths(s, ps, metaProvider) if err != nil { return nil, err diff --git a/hugolib/hugo_sites.go b/hugolib/hugo_sites.go index 662ba19d3a3..c372677713e 100644 --- a/hugolib/hugo_sites.go +++ b/hugolib/hugo_sites.go @@ -190,7 +190,7 @@ func (h *hugoSitesInit) Reset() { } func (h *HugoSites) Data() map[string]interface{} { - if _, err := h.init.data.Do(); err != nil { + if _, err := h.init.data.Do(context.TODO()); err != nil { h.SendError(errors.Wrap(err, "failed to load data")) return nil } @@ -198,7 +198,7 @@ func (h *HugoSites) Data() map[string]interface{} { } func (h *HugoSites) gitInfoForPage(p page.Page) (*gitmap.GitInfo, error) { - if _, err := h.init.gitInfo.Do(); err != nil { + if _, err := h.init.gitInfo.Do(context.TODO()); err != nil { return nil, err } @@ -210,7 +210,7 @@ func (h *HugoSites) gitInfoForPage(p page.Page) (*gitmap.GitInfo, error) { } func (h *HugoSites) codeownersForPage(p page.Page) ([]string, error) { - if _, err := h.init.gitInfo.Do(); err != nil { + if _, err := h.init.gitInfo.Do(context.TODO()); err != nil { return nil, err } @@ -359,7 +359,7 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) { donec: make(chan bool), } - h.init.data.Add(func() (interface{}, error) { + h.init.data.Add(func(ctx context.Context) (interface{}, error) { err := h.loadData(h.PathSpec.BaseFs.Data.Dirs) if err != nil { return nil, errors.Wrap(err, "failed to load data") @@ -367,7 +367,7 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) { return nil, nil }) - h.init.layouts.Add(func() (interface{}, error) { + h.init.layouts.Add(func(ctx context.Context) (interface{}, error) { for _, s := range h.Sites { if err := s.Tmpl().(tpl.TemplateManager).MarkReady(); err != nil { return nil, err @@ -376,7 +376,7 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) { return nil, nil }) - h.init.translations.Add(func() (interface{}, error) { + h.init.translations.Add(func(ctx context.Context) (interface{}, error) { if len(h.Sites) > 1 { allTranslations := pagesToTranslationsMap(h.Sites) assignTranslationsToPages(allTranslations, h.Sites) @@ -385,7 +385,7 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) { return nil, nil }) - h.init.gitInfo.Add(func() (interface{}, error) { + h.init.gitInfo.Add(func(ctx context.Context) (interface{}, error) { err := h.loadGitInfo() if err != nil { return nil, errors.Wrap(err, "failed to load Git info") diff --git a/hugolib/hugo_sites_build.go b/hugolib/hugo_sites_build.go index 6f3955b80a7..ebabdf50897 100644 --- a/hugolib/hugo_sites_build.go +++ b/hugolib/hugo_sites_build.go @@ -269,7 +269,7 @@ func (h *HugoSites) assemble(bcfg *BuildCfg) error { } func (h *HugoSites) render(config *BuildCfg) error { - if _, err := h.init.layouts.Do(); err != nil { + if _, err := h.init.layouts.Do(context.TODO()); err != nil { return err } diff --git a/hugolib/page.go b/hugolib/page.go index 7101af8143f..02b3861d99b 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -15,6 +15,7 @@ package hugolib import ( "bytes" + "context" "fmt" "os" "path" @@ -352,7 +353,7 @@ func (p *pageState) String() string { // IsTranslated returns whether this content file is translated to // other language(s). func (p *pageState) IsTranslated() bool { - p.s.h.init.translations.Do() + p.s.h.init.translations.Do(context.TODO()) return len(p.translations) > 0 } @@ -376,13 +377,13 @@ func (p *pageState) TranslationKey() string { // AllTranslations returns all translations, including the current Page. func (p *pageState) AllTranslations() page.Pages { - p.s.h.init.translations.Do() + p.s.h.init.translations.Do(context.TODO()) return p.allTranslations } // Translations returns the translations excluding the current Page. func (p *pageState) Translations() page.Pages { - p.s.h.init.translations.Do() + p.s.h.init.translations.Do(context.TODO()) return p.translations } @@ -462,7 +463,7 @@ func (p *pageState) initOutputFormat(isRenderingSite bool, idx int) error { // Must be run after the site section tree etc. is built and ready. func (p *pageState) initPage() error { - if _, err := p.init.Do(); err != nil { + if _, err := p.init.Do(context.TODO()); err != nil { return err } return nil diff --git a/hugolib/page__menus.go b/hugolib/page__menus.go index 49d392c2fc2..46de55714eb 100644 --- a/hugolib/page__menus.go +++ b/hugolib/page__menus.go @@ -14,6 +14,7 @@ package hugolib import ( + "context" "sync" "github.com/gohugoio/hugo/navigation" @@ -29,13 +30,13 @@ type pageMenus struct { } func (p *pageMenus) HasMenuCurrent(menuID string, me *navigation.MenuEntry) bool { - p.p.s.init.menus.Do() + p.p.s.init.menus.Do(context.TODO()) p.init() return p.q.HasMenuCurrent(menuID, me) } func (p *pageMenus) IsMenuCurrent(menuID string, inme *navigation.MenuEntry) bool { - p.p.s.init.menus.Do() + p.p.s.init.menus.Do(context.TODO()) p.init() return p.q.IsMenuCurrent(menuID, inme) } @@ -43,7 +44,7 @@ func (p *pageMenus) IsMenuCurrent(menuID string, inme *navigation.MenuEntry) boo func (p *pageMenus) Menus() navigation.PageMenus { // There is a reverse dependency here. initMenus will, once, build the // site menus and update any relevant page. - p.p.s.init.menus.Do() + p.p.s.init.menus.Do(context.TODO()) return p.menus() } diff --git a/hugolib/page__new.go b/hugolib/page__new.go index b8395d5ca06..6041fb90255 100644 --- a/hugolib/page__new.go +++ b/hugolib/page__new.go @@ -14,6 +14,7 @@ package hugolib import ( + "context" "html/template" "strings" @@ -119,7 +120,7 @@ func newPageFromMeta( return nil, err } - ps.init.Add(func() (interface{}, error) { + ps.init.Add(func(ctx context.Context) (interface{}, error) { pp, err := newPagePaths(metaProvider.s, ps, metaProvider) if err != nil { return nil, err diff --git a/hugolib/page__per_output.go b/hugolib/page__per_output.go index 29beb672e55..b01fab10580 100644 --- a/hugolib/page__per_output.go +++ b/hugolib/page__per_output.go @@ -83,7 +83,7 @@ func newPageContentOutput(p *pageState, po *pageOutput) (*pageContentOutput, err renderHooks: &renderHooks{}, } - initContent := func() (err error) { + initContent := func(ctx context.Context) (err error) { p.s.h.IncrContentRender() if p.cmap == nil { @@ -105,7 +105,7 @@ func newPageContentOutput(p *pageState, po *pageOutput) (*pageContentOutput, err var hasShortcodeVariants bool f := po.f - cp.contentPlaceholders, hasShortcodeVariants, err = p.shortcodeState.renderShortcodesForPage(p, f) + cp.contentPlaceholders, hasShortcodeVariants, err = p.shortcodeState.renderShortcodesForPage(ctx, p, f) if err != nil { return err } @@ -119,7 +119,7 @@ func newPageContentOutput(p *pageState, po *pageOutput) (*pageContentOutput, err isHTML := cp.p.m.markup == "html" if !isHTML { - r, err := cp.renderContent(cp.workContent, true) + r, err := cp.renderContent(ctx, cp.workContent, true) if err != nil { return err } @@ -179,7 +179,7 @@ func newPageContentOutput(p *pageState, po *pageOutput) (*pageContentOutput, err } } } else if cp.p.m.summary != "" { - b, err := cp.renderContent([]byte(cp.p.m.summary), false) + b, err := cp.renderContent(ctx, []byte(cp.p.m.summary), false) if err != nil { return err } @@ -194,10 +194,10 @@ func newPageContentOutput(p *pageState, po *pageOutput) (*pageContentOutput, err // There may be recursive loops in shortcodes and render hooks. cp.initMain = parent.BranchWithTimeout(p.s.siteCfg.timeout, func(ctx context.Context) (interface{}, error) { - return nil, initContent() + return nil, initContent(ctx) }) - cp.initPlain = cp.initMain.Branch(func() (interface{}, error) { + cp.initPlain = cp.initMain.Branch(func(ctx context.Context) (interface{}, error) { cp.plain = helpers.StripHTML(string(cp.content)) cp.plainWords = strings.Fields(cp.plain) cp.setWordCounts(p.m.isCJKLanguage) @@ -270,65 +270,65 @@ func (p *pageContentOutput) Reset() { p.renderHooks = &renderHooks{} } -func (p *pageContentOutput) Content() (interface{}, error) { - if p.p.s.initInit(p.initMain, p.p) { +func (p *pageContentOutput) Content(ctx context.Context) (interface{}, error) { + if p.p.s.initInit(ctx, p.initMain, p.p) { return p.content, nil } return nil, nil } -func (p *pageContentOutput) FuzzyWordCount() int { - p.p.s.initInit(p.initPlain, p.p) +func (p *pageContentOutput) FuzzyWordCount(ctx context.Context) int { + p.p.s.initInit(ctx, p.initPlain, p.p) return p.fuzzyWordCount } -func (p *pageContentOutput) Len() int { - p.p.s.initInit(p.initMain, p.p) +func (p *pageContentOutput) Len(ctx context.Context) int { + p.p.s.initInit(ctx, p.initMain, p.p) return len(p.content) } -func (p *pageContentOutput) Plain() string { - p.p.s.initInit(p.initPlain, p.p) +func (p *pageContentOutput) Plain(ctx context.Context) string { + p.p.s.initInit(ctx, p.initPlain, p.p) return p.plain } -func (p *pageContentOutput) PlainWords() []string { - p.p.s.initInit(p.initPlain, p.p) +func (p *pageContentOutput) PlainWords(ctx context.Context) []string { + p.p.s.initInit(ctx, p.initPlain, p.p) return p.plainWords } -func (p *pageContentOutput) ReadingTime() int { - p.p.s.initInit(p.initPlain, p.p) +func (p *pageContentOutput) ReadingTime(ctx context.Context) int { + p.p.s.initInit(ctx, p.initPlain, p.p) return p.readingTime } -func (p *pageContentOutput) Summary() template.HTML { - p.p.s.initInit(p.initMain, p.p) +func (p *pageContentOutput) Summary(ctx context.Context) template.HTML { + p.p.s.initInit(ctx, p.initMain, p.p) if !p.p.source.hasSummaryDivider { - p.p.s.initInit(p.initPlain, p.p) + p.p.s.initInit(ctx, p.initPlain, p.p) } return p.summary } -func (p *pageContentOutput) TableOfContents() template.HTML { - p.p.s.initInit(p.initMain, p.p) +func (p *pageContentOutput) TableOfContents(ctx context.Context) template.HTML { + p.p.s.initInit(ctx, p.initMain, p.p) return p.tableOfContents } -func (p *pageContentOutput) Truncated() bool { +func (p *pageContentOutput) Truncated(ctx context.Context) bool { if p.p.truncated { return true } - p.p.s.initInit(p.initPlain, p.p) + p.p.s.initInit(ctx, p.initPlain, p.p) return p.truncated } -func (p *pageContentOutput) WordCount() int { - p.p.s.initInit(p.initPlain, p.p) +func (p *pageContentOutput) WordCount(ctx context.Context) int { + p.p.s.initInit(ctx, p.initPlain, p.p) return p.wordCount } -func (p *pageContentOutput) RenderString(args ...interface{}) (template.HTML, error) { +func (p *pageContentOutput) RenderString(ctx context.Context, args ...interface{}) (template.HTML, error) { if len(args) < 1 || len(args) > 2 { return "", errors.New("want 1 or 2 arguments") } @@ -370,7 +370,7 @@ func (p *pageContentOutput) RenderString(args ...interface{}) (template.HTML, er } } - c, err := p.renderContentWithConverter(conv, []byte(s), false) + c, err := p.renderContentWithConverter(ctx, conv, []byte(s), false) if err != nil { return "", p.p.wrapError(err) } @@ -386,12 +386,12 @@ func (p *pageContentOutput) RenderString(args ...interface{}) (template.HTML, er return template.HTML(string(b)), nil } -func (p *pageContentOutput) RenderWithTemplateInfo(info tpl.Info, layout ...string) (template.HTML, error) { +func (p *pageContentOutput) RenderWithTemplateInfo(ctx context.Context, info tpl.Info, layout ...string) (template.HTML, error) { p.p.addDependency(info) - return p.Render(layout...) + return p.Render(ctx, layout...) } -func (p *pageContentOutput) Render(layout ...string) (template.HTML, error) { +func (p *pageContentOutput) Render(ctx context.Context, layout ...string) (template.HTML, error) { templ, found, err := p.p.resolveTemplate(layout...) if err != nil { return "", p.p.wrapError(err) @@ -539,17 +539,18 @@ func (p *pageContentOutput) setAutoSummary() error { return nil } -func (cp *pageContentOutput) renderContent(content []byte, renderTOC bool) (converter.Result, error) { +func (cp *pageContentOutput) renderContent(ctx context.Context, content []byte, renderTOC bool) (converter.Result, error) { if err := cp.initRenderHooks(); err != nil { return nil, err } c := cp.p.getContentConverter() - return cp.renderContentWithConverter(c, content, renderTOC) + return cp.renderContentWithConverter(ctx, c, content, renderTOC) } -func (cp *pageContentOutput) renderContentWithConverter(c converter.Converter, content []byte, renderTOC bool) (converter.Result, error) { +func (cp *pageContentOutput) renderContentWithConverter(ctx context.Context, c converter.Converter, content []byte, renderTOC bool) (converter.Result, error) { r, err := c.Convert( converter.RenderContext{ + Ctx: ctx, Src: content, RenderTOC: renderTOC, GetRenderer: cp.renderHooks.getRenderer, diff --git a/hugolib/page__position.go b/hugolib/page__position.go index a087872cc0a..24df2997916 100644 --- a/hugolib/page__position.go +++ b/hugolib/page__position.go @@ -14,6 +14,8 @@ package hugolib import ( + "context" + "github.com/gohugoio/hugo/lazy" "github.com/gohugoio/hugo/resources/page" ) @@ -33,12 +35,12 @@ type nextPrev struct { } func (n *nextPrev) next() page.Page { - n.init.Do() + n.init.Do(context.TODO()) return n.nextPage } func (n *nextPrev) prev() page.Page { - n.init.Do() + n.init.Do(context.TODO()) return n.prevPage } diff --git a/hugolib/shortcode.go b/hugolib/shortcode.go index ec3a4a01bbb..429b6cb9e85 100644 --- a/hugolib/shortcode.go +++ b/hugolib/shortcode.go @@ -15,6 +15,7 @@ package hugolib import ( "bytes" + "context" "fmt" "html/template" "path" @@ -272,6 +273,7 @@ const ( ) func renderShortcode( + ctx context.Context, level int, s *Site, tplVariants tpl.TemplateVariants, @@ -333,7 +335,7 @@ func renderShortcode( case string: inner += innerData case *shortcode: - s, more, err := renderShortcode(level+1, s, tplVariants, innerData, data, p) + s, more, err := renderShortcode(ctx, level+1, s, tplVariants, innerData, data, p) if err != nil { return "", false, err } @@ -350,7 +352,7 @@ func renderShortcode( // shortcode. if sc.doMarkup && (level > 0 || sc.configVersion() == 1) { var err error - b, err := p.pageOutput.cp.renderContent([]byte(inner), false) + b, err := p.pageOutput.cp.renderContent(ctx, []byte(inner), false) if err != nil { return "", false, err } @@ -386,7 +388,7 @@ func renderShortcode( } - result, err := renderShortcodeWithPage(s.Tmpl(), tmpl, data) + result, err := renderShortcodeWithPage(ctx, s.Tmpl(), tmpl, data) if err != nil && sc.isInline { fe := herrors.ToFileError("html", err) @@ -402,7 +404,7 @@ func (s *shortcodeHandler) hasShortcodes() bool { return s != nil && len(s.shortcodes) > 0 } -func (s *shortcodeHandler) renderShortcodesForPage(p *pageState, f output.Format) (map[string]string, bool, error) { +func (s *shortcodeHandler) renderShortcodesForPage(ctx context.Context, p *pageState, f output.Format) (map[string]string, bool, error) { rendered := make(map[string]string) tplVariants := tpl.TemplateVariants{ @@ -413,7 +415,7 @@ func (s *shortcodeHandler) renderShortcodesForPage(p *pageState, f output.Format var hasVariants bool for _, v := range s.shortcodes { - s, more, err := renderShortcode(0, s.s, tplVariants, v, nil, p) + s, more, err := renderShortcode(ctx, 0, s.s, tplVariants, v, nil, p) if err != nil { err = p.parseError(errors.Wrapf(err, "failed to render shortcode %q", v.name), p.source.parsed.Input(), v.pos) return nil, false, err @@ -633,11 +635,11 @@ func replaceShortcodeTokens(source []byte, replacements map[string]string) ([]by return source, nil } -func renderShortcodeWithPage(h tpl.TemplateHandler, tmpl tpl.Template, data *ShortcodeWithPage) (string, error) { +func renderShortcodeWithPage(ctx context.Context, h tpl.TemplateHandler, tmpl tpl.Template, data *ShortcodeWithPage) (string, error) { buffer := bp.GetBuffer() defer bp.PutBuffer(buffer) - err := h.Execute(tmpl, buffer, data) + err := h.ExecuteWithContext(ctx, tmpl, buffer, data) if err != nil { return "", errors.Wrap(err, "failed to process shortcode") } diff --git a/hugolib/shortcode_page.go b/hugolib/shortcode_page.go index 5a56e434f2f..a5d9e35dff2 100644 --- a/hugolib/shortcode_page.go +++ b/hugolib/shortcode_page.go @@ -14,6 +14,7 @@ package hugolib import ( + "context" "html/template" "github.com/gohugoio/hugo/resources/page" @@ -50,7 +51,7 @@ func (p *pageForShortcode) page() page.Page { return p.PageWithoutContent.(page.Page) } -func (p *pageForShortcode) TableOfContents() template.HTML { +func (p *pageForShortcode) TableOfContents(context.Context) template.HTML { p.p.enablePlaceholders() return p.toc } diff --git a/hugolib/site.go b/hugolib/site.go index 57821ee93c4..ceb3b75752f 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -14,6 +14,7 @@ package hugolib import ( + "context" "fmt" "html/template" "io" @@ -174,7 +175,7 @@ type Site struct { } func (s *Site) Taxonomies() TaxonomyList { - s.init.taxonomies.Do() + s.init.taxonomies.Do(context.TODO()) return s.taxonomies } @@ -215,8 +216,8 @@ func (init *siteInit) Reset() { init.taxonomies.Reset() } -func (s *Site) initInit(init *lazy.Init, pctx pageContext) bool { - _, err := init.Do() +func (s *Site) initInit(ctx context.Context, init *lazy.Init, pctx pageContext) bool { + _, err := init.Do(ctx) if err != nil { s.h.FatalError(pctx.wrapError(err)) } @@ -228,7 +229,7 @@ func (s *Site) prepareInits() { var init lazy.Init - s.init.prevNext = init.Branch(func() (interface{}, error) { + s.init.prevNext = init.Branch(func(ctx context.Context) (interface{}, error) { regularPages := s.RegularPages() for i, p := range regularPages { np, ok := p.(nextPrevProvider) @@ -255,7 +256,7 @@ func (s *Site) prepareInits() { return nil, nil }) - s.init.prevNextInSection = init.Branch(func() (interface{}, error) { + s.init.prevNextInSection = init.Branch(func(ctx context.Context) (interface{}, error) { var sections page.Pages s.home.treeRef.m.collectSectionsRecursiveIncludingSelf(pageMapQuery{Prefix: s.home.treeRef.key}, func(n *contentNode) { sections = append(sections, n.p) @@ -312,12 +313,12 @@ func (s *Site) prepareInits() { return nil, nil }) - s.init.menus = init.Branch(func() (interface{}, error) { + s.init.menus = init.Branch(func(ctx context.Context) (interface{}, error) { s.assembleMenus() return nil, nil }) - s.init.taxonomies = init.Branch(func() (interface{}, error) { + s.init.taxonomies = init.Branch(func(ctx context.Context) (interface{}, error) { err := s.pageMap.assembleTaxonomies() return nil, err }) @@ -328,7 +329,7 @@ type siteRenderingContext struct { } func (s *Site) Menus() navigation.Menus { - s.init.menus.Do() + s.init.menus.Do(context.TODO()) return s.menus } @@ -1781,16 +1782,16 @@ type hookRendererTemplate struct { templ tpl.Template } -func (hr hookRendererTemplate) RenderLink(w io.Writer, ctx hooks.LinkContext) error { - return hr.templateHandler.Execute(hr.templ, w, ctx) +func (hr hookRendererTemplate) RenderLink(ctx context.Context, w io.Writer, rctx hooks.LinkContext) error { + return hr.templateHandler.ExecuteWithContext(ctx, hr.templ, w, rctx) } -func (hr hookRendererTemplate) RenderHeading(w io.Writer, ctx hooks.HeadingContext) error { - return hr.templateHandler.Execute(hr.templ, w, ctx) +func (hr hookRendererTemplate) RenderHeading(ctx context.Context, w io.Writer, rctx hooks.HeadingContext) error { + return hr.templateHandler.ExecuteWithContext(ctx, hr.templ, w, rctx) } -func (hr hookRendererTemplate) RenderCodeblock(w hugio.FlexiWriter, ctx hooks.CodeblockContext) error { - return hr.templateHandler.Execute(hr.templ, w, ctx) +func (hr hookRendererTemplate) RenderCodeblock(ctx context.Context, w hugio.FlexiWriter, rctx hooks.CodeblockContext) error { + return hr.templateHandler.ExecuteWithContext(ctx, hr.templ, w, rctx) } func (s *Site) renderForTemplate(name, outputFormat string, d interface{}, w io.Writer, templ tpl.Template) (err error) { @@ -1799,7 +1800,9 @@ func (s *Site) renderForTemplate(name, outputFormat string, d interface{}, w io. return nil } - if err = s.Tmpl().Execute(templ, w, d); err != nil { + ctx := tpl.SetDataInContext(context.Background(), d) + + if err = s.Tmpl().ExecuteWithContext(ctx, templ, w, d); err != nil { return _errors.Wrapf(err, "render of %q failed", name) } return diff --git a/lazy/init.go b/lazy/init.go index fc64b2a7da3..c62633c4a29 100644 --- a/lazy/init.go +++ b/lazy/init.go @@ -40,11 +40,11 @@ type Init struct { init onceMore out interface{} err error - f func() (interface{}, error) + f func(ctx context.Context) (interface{}, error) } // Add adds a func as a new child dependency. -func (ini *Init) Add(initFn func() (interface{}, error)) *Init { +func (ini *Init) Add(initFn func(ctx context.Context) (interface{}, error)) *Init { if ini == nil { ini = New() } @@ -59,14 +59,14 @@ func (ini *Init) InitCount() int { // AddWithTimeout is same as Add, but with a timeout that aborts initialization. func (ini *Init) AddWithTimeout(timeout time.Duration, f func(ctx context.Context) (interface{}, error)) *Init { - return ini.Add(func() (interface{}, error) { - return ini.withTimeout(timeout, f) + return ini.Add(func(ctx context.Context) (interface{}, error) { + return ini.withTimeout(ctx, timeout, f) }) } // Branch creates a new dependency branch based on an existing and adds // the given dependency as a child. -func (ini *Init) Branch(initFn func() (interface{}, error)) *Init { +func (ini *Init) Branch(initFn func(ctx context.Context) (interface{}, error)) *Init { if ini == nil { ini = New() } @@ -75,13 +75,13 @@ func (ini *Init) Branch(initFn func() (interface{}, error)) *Init { // BranchdWithTimeout is same as Branch, but with a timeout. func (ini *Init) BranchWithTimeout(timeout time.Duration, f func(ctx context.Context) (interface{}, error)) *Init { - return ini.Branch(func() (interface{}, error) { - return ini.withTimeout(timeout, f) + return ini.Branch(func(ctx context.Context) (interface{}, error) { + return ini.withTimeout(ctx, timeout, f) }) } // Do initializes the entire dependency graph. -func (ini *Init) Do() (interface{}, error) { +func (ini *Init) Do(ctx context.Context) (interface{}, error) { if ini == nil { panic("init is nil") } @@ -92,7 +92,7 @@ func (ini *Init) Do() (interface{}, error) { if prev != nil { // A branch. Initialize the ancestors. if prev.shouldInitialize() { - _, err := prev.Do() + _, err := prev.Do(ctx) if err != nil { ini.err = err return @@ -105,12 +105,12 @@ func (ini *Init) Do() (interface{}, error) { } if ini.f != nil { - ini.out, ini.err = ini.f() + ini.out, ini.err = ini.f(ctx) } for _, child := range ini.children { if child.shouldInitialize() { - _, err := child.Do() + _, err := child.Do(ctx) if err != nil { ini.err = err return @@ -154,7 +154,7 @@ func (ini *Init) Reset() { } } -func (ini *Init) add(branch bool, initFn func() (interface{}, error)) *Init { +func (ini *Init) add(branch bool, initFn func(ctx context.Context) (interface{}, error)) *Init { ini.mu.Lock() defer ini.mu.Unlock() @@ -179,8 +179,8 @@ func (ini *Init) checkDone() { } } -func (ini *Init) withTimeout(timeout time.Duration, f func(ctx context.Context) (interface{}, error)) (interface{}, error) { - ctx, cancel := context.WithTimeout(context.Background(), timeout) +func (ini *Init) withTimeout(ctx context.Context, timeout time.Duration, f func(ctx context.Context) (interface{}, error)) (interface{}, error) { + ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() c := make(chan verr, 1) diff --git a/markup/converter/converter.go b/markup/converter/converter.go index 30addfec657..ebbb8e42ae4 100644 --- a/markup/converter/converter.go +++ b/markup/converter/converter.go @@ -15,6 +15,7 @@ package converter import ( "bytes" + "context" "github.com/gohugoio/hugo/common/hexec" "github.com/gohugoio/hugo/common/loggers" @@ -128,6 +129,7 @@ type DocumentContext struct { // RenderContext holds contextual information about the content to render. type RenderContext struct { + Ctx context.Context Src []byte RenderTOC bool diff --git a/markup/converter/hooks/hooks.go b/markup/converter/hooks/hooks.go index 987cb1dc36b..6e4f8097052 100644 --- a/markup/converter/hooks/hooks.go +++ b/markup/converter/hooks/hooks.go @@ -14,6 +14,7 @@ package hooks import ( + "context" "io" "github.com/gohugoio/hugo/common/hugio" @@ -50,12 +51,12 @@ type AttributesOptionsSliceProvider interface { } type LinkRenderer interface { - RenderLink(w io.Writer, ctx LinkContext) error + RenderLink(context.Context, io.Writer, LinkContext) error identity.Provider } type CodeBlockRenderer interface { - RenderCodeblock(w hugio.FlexiWriter, ctx CodeblockContext) error + RenderCodeblock(context.Context, hugio.FlexiWriter, CodeblockContext) error identity.Provider } @@ -80,7 +81,7 @@ type HeadingContext interface { // HeadingRenderer describes a uniquely identifiable rendering hook. type HeadingRenderer interface { // Render writes the rendered content to w using the data in w. - RenderHeading(w io.Writer, ctx HeadingContext) error + RenderHeading(context.Context, io.Writer, HeadingContext) error identity.Provider } diff --git a/markup/goldmark/codeblocks/render.go b/markup/goldmark/codeblocks/render.go index 59d142e23d0..176865534e6 100644 --- a/markup/goldmark/codeblocks/render.go +++ b/markup/goldmark/codeblocks/render.go @@ -91,6 +91,7 @@ func (r *htmlRenderer) renderCodeBlock(w util.BufWriter, src []byte, node ast.No cr := v.(hooks.CodeBlockRenderer) err := cr.RenderCodeblock( + ctx.RenderContext().Ctx, w, codeBlockContext{ page: ctx.DocumentContext().Document, diff --git a/markup/goldmark/render_hooks.go b/markup/goldmark/render_hooks.go index d5e35380a11..132550f15fb 100644 --- a/markup/goldmark/render_hooks.go +++ b/markup/goldmark/render_hooks.go @@ -148,6 +148,7 @@ func (r *hookedRenderer) renderImage(w util.BufWriter, source []byte, node ast.N ctx.Buffer.Truncate(pos) err := lr.RenderLink( + ctx.RenderContext().Ctx, w, linkContext{ page: ctx.DocumentContext().Document, @@ -218,6 +219,7 @@ func (r *hookedRenderer) renderLink(w util.BufWriter, source []byte, node ast.No ctx.Buffer.Truncate(pos) err := lr.RenderLink( + ctx.RenderContext().Ctx, w, linkContext{ page: ctx.DocumentContext().Document, @@ -286,6 +288,7 @@ func (r *hookedRenderer) renderAutoLink(w util.BufWriter, source []byte, node as } err := lr.RenderLink( + ctx.RenderContext().Ctx, w, linkContext{ page: ctx.DocumentContext().Document, @@ -361,6 +364,7 @@ func (r *hookedRenderer) renderHeading(w util.BufWriter, source []byte, node ast anchor := anchori.([]byte) err := hr.RenderHeading( + ctx.RenderContext().Ctx, w, headingContext{ page: ctx.DocumentContext().Document, diff --git a/markup/highlight/highlight.go b/markup/highlight/highlight.go index e9cbeb3c991..b0dc4ff32fe 100644 --- a/markup/highlight/highlight.go +++ b/markup/highlight/highlight.go @@ -14,6 +14,7 @@ package highlight import ( + "context" "fmt" gohtml "html" "html/template" @@ -108,15 +109,15 @@ func (h chromaHighlighter) HighlightCodeBlock(ctx hooks.CodeblockContext, opts i }, nil } -func (h chromaHighlighter) RenderCodeblock(w hugio.FlexiWriter, ctx hooks.CodeblockContext) error { +func (h chromaHighlighter) RenderCodeblock(ctx context.Context, w hugio.FlexiWriter, ctxt hooks.CodeblockContext) error { cfg := h.cfg - attributes := ctx.(hooks.AttributesOptionsSliceProvider).AttributesSlice() + attributes := ctxt.(hooks.AttributesOptionsSliceProvider).AttributesSlice() - if err := applyOptionsFromMap(ctx.Options(), &cfg); err != nil { + if err := applyOptionsFromMap(ctxt.Options(), &cfg); err != nil { return err } - return highlight(w, ctx.Code(), ctx.Lang(), attributes, cfg) + return highlight(w, ctxt.Code(), ctxt.Lang(), attributes, cfg) } var id = identity.NewPathIdentity("chroma", "highlight") diff --git a/resources/page/page.go b/resources/page/page.go index 797322717ca..106e4e21344 100644 --- a/resources/page/page.go +++ b/resources/page/page.go @@ -16,6 +16,7 @@ package page import ( + "context" "html/template" "github.com/gohugoio/hugo/identity" @@ -75,15 +76,15 @@ type ChildCareProvider interface { // ContentProvider provides the content related values for a Page. type ContentProvider interface { - Content() (interface{}, error) - Plain() string - PlainWords() []string - Summary() template.HTML - Truncated() bool - FuzzyWordCount() int - WordCount() int - ReadingTime() int - Len() int + Content(ctx context.Context) (interface{}, error) + Plain(ctx context.Context) string + PlainWords(ctx context.Context) []string + Summary(ctx context.Context) template.HTML + Truncated(ctx context.Context) bool + FuzzyWordCount(ctx context.Context) int + WordCount(ctx context.Context) int + ReadingTime(ctx context.Context) int + Len(ctx context.Context) int } // FileProvider provides the source file. @@ -216,8 +217,8 @@ type PageMetaProvider interface { // PageRenderProvider provides a way for a Page to render content. type PageRenderProvider interface { - Render(layout ...string) (template.HTML, error) - RenderString(args ...interface{}) (template.HTML, error) + Render(ctx context.Context, layout ...string) (template.HTML, error) + RenderString(ctx context.Context, args ...interface{}) (template.HTML, error) } // PageWithoutContent is the Page without any of the content methods. @@ -330,7 +331,7 @@ type SitesProvider interface { // TableOfContentsProvider provides the table of contents for a Page. type TableOfContentsProvider interface { - TableOfContents() template.HTML + TableOfContents(ctx context.Context) template.HTML } // TranslationsProvider provides access to any translations. diff --git a/resources/page/page_lazy_contentprovider.go b/resources/page/page_lazy_contentprovider.go index 206695d181a..5c49dfe69a0 100644 --- a/resources/page/page_lazy_contentprovider.go +++ b/resources/page/page_lazy_contentprovider.go @@ -14,6 +14,7 @@ package page import ( + "context" "html/template" "github.com/gohugoio/hugo/lazy" @@ -48,7 +49,7 @@ func NewLazyContentProvider(f func() (OutputFormatContentProvider, error)) *Lazy init: lazy.New(), cp: NopPage, } - lcp.init.Add(func() (interface{}, error) { + lcp.init.Add(func(ctx context.Context) (interface{}, error) { cp, err := f() if err != nil { return nil, err @@ -63,62 +64,62 @@ func (lcp *LazyContentProvider) Reset() { lcp.init.Reset() } -func (lcp *LazyContentProvider) Content() (interface{}, error) { - lcp.init.Do() - return lcp.cp.Content() +func (lcp *LazyContentProvider) Content(ctx context.Context) (interface{}, error) { + lcp.init.Do(ctx) + return lcp.cp.Content(ctx) } -func (lcp *LazyContentProvider) Plain() string { - lcp.init.Do() - return lcp.cp.Plain() +func (lcp *LazyContentProvider) Plain(ctx context.Context) string { + lcp.init.Do(ctx) + return lcp.cp.Plain(ctx) } -func (lcp *LazyContentProvider) PlainWords() []string { - lcp.init.Do() - return lcp.cp.PlainWords() +func (lcp *LazyContentProvider) PlainWords(ctx context.Context) []string { + lcp.init.Do(ctx) + return lcp.cp.PlainWords(ctx) } -func (lcp *LazyContentProvider) Summary() template.HTML { - lcp.init.Do() - return lcp.cp.Summary() +func (lcp *LazyContentProvider) Summary(ctx context.Context) template.HTML { + lcp.init.Do(ctx) + return lcp.cp.Summary(ctx) } -func (lcp *LazyContentProvider) Truncated() bool { - lcp.init.Do() - return lcp.cp.Truncated() +func (lcp *LazyContentProvider) Truncated(ctx context.Context) bool { + lcp.init.Do(ctx) + return lcp.cp.Truncated(ctx) } -func (lcp *LazyContentProvider) FuzzyWordCount() int { - lcp.init.Do() - return lcp.cp.FuzzyWordCount() +func (lcp *LazyContentProvider) FuzzyWordCount(ctx context.Context) int { + lcp.init.Do(ctx) + return lcp.cp.FuzzyWordCount(ctx) } -func (lcp *LazyContentProvider) WordCount() int { - lcp.init.Do() - return lcp.cp.WordCount() +func (lcp *LazyContentProvider) WordCount(ctx context.Context) int { + lcp.init.Do(ctx) + return lcp.cp.WordCount(ctx) } -func (lcp *LazyContentProvider) ReadingTime() int { - lcp.init.Do() - return lcp.cp.ReadingTime() +func (lcp *LazyContentProvider) ReadingTime(ctx context.Context) int { + lcp.init.Do(ctx) + return lcp.cp.ReadingTime(ctx) } -func (lcp *LazyContentProvider) Len() int { - lcp.init.Do() - return lcp.cp.Len() +func (lcp *LazyContentProvider) Len(ctx context.Context) int { + lcp.init.Do(ctx) + return lcp.cp.Len(ctx) } -func (lcp *LazyContentProvider) Render(layout ...string) (template.HTML, error) { - lcp.init.Do() - return lcp.cp.Render(layout...) +func (lcp *LazyContentProvider) Render(ctx context.Context, layout ...string) (template.HTML, error) { + lcp.init.Do(ctx) + return lcp.cp.Render(ctx, layout...) } -func (lcp *LazyContentProvider) RenderString(args ...interface{}) (template.HTML, error) { - lcp.init.Do() - return lcp.cp.RenderString(args...) +func (lcp *LazyContentProvider) RenderString(ctx context.Context, args ...interface{}) (template.HTML, error) { + lcp.init.Do(ctx) + return lcp.cp.RenderString(ctx, args...) } -func (lcp *LazyContentProvider) TableOfContents() template.HTML { - lcp.init.Do() - return lcp.cp.TableOfContents() +func (lcp *LazyContentProvider) TableOfContents(ctx context.Context) template.HTML { + lcp.init.Do(ctx) + return lcp.cp.TableOfContents(ctx) } diff --git a/resources/page/page_marshaljson.autogen.go b/resources/page/page_marshaljson.autogen.go index 7b44d4a7201..dcd86db7f39 100644 --- a/resources/page/page_marshaljson.autogen.go +++ b/resources/page/page_marshaljson.autogen.go @@ -15,197 +15,7 @@ package page -import ( - "encoding/json" - "github.com/bep/gitmap" - "github.com/gohugoio/hugo/common/maps" - "github.com/gohugoio/hugo/config" - "github.com/gohugoio/hugo/hugofs/files" - "github.com/gohugoio/hugo/identity" - "github.com/gohugoio/hugo/langs" - "github.com/gohugoio/hugo/media" - "github.com/gohugoio/hugo/navigation" - "github.com/gohugoio/hugo/source" - "html/template" - "time" -) - func MarshalPageToJSON(p Page) ([]byte, error) { - content, err := p.Content() - if err != nil { - return nil, err - } - plain := p.Plain() - plainWords := p.PlainWords() - summary := p.Summary() - truncated := p.Truncated() - fuzzyWordCount := p.FuzzyWordCount() - wordCount := p.WordCount() - readingTime := p.ReadingTime() - length := p.Len() - tableOfContents := p.TableOfContents() - rawContent := p.RawContent() - resourceType := p.ResourceType() - mediaType := p.MediaType() - permalink := p.Permalink() - relPermalink := p.RelPermalink() - name := p.Name() - title := p.Title() - params := p.Params() - data := p.Data() - date := p.Date() - lastmod := p.Lastmod() - publishDate := p.PublishDate() - expiryDate := p.ExpiryDate() - aliases := p.Aliases() - bundleType := p.BundleType() - description := p.Description() - draft := p.Draft() - isHome := p.IsHome() - keywords := p.Keywords() - kind := p.Kind() - layout := p.Layout() - linkTitle := p.LinkTitle() - isNode := p.IsNode() - isPage := p.IsPage() - path := p.Path() - pathc := p.Pathc() - slug := p.Slug() - lang := p.Lang() - isSection := p.IsSection() - section := p.Section() - sectionsEntries := p.SectionsEntries() - sectionsPath := p.SectionsPath() - sitemap := p.Sitemap() - typ := p.Type() - weight := p.Weight() - language := p.Language() - file := p.File() - gitInfo := p.GitInfo() - outputFormats := p.OutputFormats() - alternativeOutputFormats := p.AlternativeOutputFormats() - menus := p.Menus() - translationKey := p.TranslationKey() - isTranslated := p.IsTranslated() - allTranslations := p.AllTranslations() - translations := p.Translations() - getIdentity := p.GetIdentity() - - s := struct { - Content interface{} - Plain string - PlainWords []string - Summary template.HTML - Truncated bool - FuzzyWordCount int - WordCount int - ReadingTime int - Len int - TableOfContents template.HTML - RawContent string - ResourceType string - MediaType media.Type - Permalink string - RelPermalink string - Name string - Title string - Params maps.Params - Data interface{} - Date time.Time - Lastmod time.Time - PublishDate time.Time - ExpiryDate time.Time - Aliases []string - BundleType files.ContentClass - Description string - Draft bool - IsHome bool - Keywords []string - Kind string - Layout string - LinkTitle string - IsNode bool - IsPage bool - Path string - Pathc string - Slug string - Lang string - IsSection bool - Section string - SectionsEntries []string - SectionsPath string - Sitemap config.Sitemap - Type string - Weight int - Language *langs.Language - File source.File - GitInfo *gitmap.GitInfo - OutputFormats OutputFormats - AlternativeOutputFormats OutputFormats - Menus navigation.PageMenus - TranslationKey string - IsTranslated bool - AllTranslations Pages - Translations Pages - GetIdentity identity.Identity - }{ - Content: content, - Plain: plain, - PlainWords: plainWords, - Summary: summary, - Truncated: truncated, - FuzzyWordCount: fuzzyWordCount, - WordCount: wordCount, - ReadingTime: readingTime, - Len: length, - TableOfContents: tableOfContents, - RawContent: rawContent, - ResourceType: resourceType, - MediaType: mediaType, - Permalink: permalink, - RelPermalink: relPermalink, - Name: name, - Title: title, - Params: params, - Data: data, - Date: date, - Lastmod: lastmod, - PublishDate: publishDate, - ExpiryDate: expiryDate, - Aliases: aliases, - BundleType: bundleType, - Description: description, - Draft: draft, - IsHome: isHome, - Keywords: keywords, - Kind: kind, - Layout: layout, - LinkTitle: linkTitle, - IsNode: isNode, - IsPage: isPage, - Path: path, - Pathc: pathc, - Slug: slug, - Lang: lang, - IsSection: isSection, - Section: section, - SectionsEntries: sectionsEntries, - SectionsPath: sectionsPath, - Sitemap: sitemap, - Type: typ, - Weight: weight, - Language: language, - File: file, - GitInfo: gitInfo, - OutputFormats: outputFormats, - AlternativeOutputFormats: alternativeOutputFormats, - Menus: menus, - TranslationKey: translationKey, - IsTranslated: isTranslated, - AllTranslations: allTranslations, - Translations: translations, - GetIdentity: getIdentity, - } - - return json.Marshal(&s) + // TODO1 + return nil, nil } diff --git a/resources/page/page_nop.go b/resources/page/page_nop.go index 641c34d41bf..08990473a81 100644 --- a/resources/page/page_nop.go +++ b/resources/page/page_nop.go @@ -16,6 +16,7 @@ package page import ( + "context" "html/template" "time" @@ -96,7 +97,7 @@ func (p *nopPage) BundleType() files.ContentClass { return "" } -func (p *nopPage) Content() (interface{}, error) { +func (p *nopPage) Content(context.Context) (interface{}, error) { return "", nil } @@ -170,7 +171,7 @@ func (p *nopPage) FirstSection() Page { return nil } -func (p *nopPage) FuzzyWordCount() int { +func (p *nopPage) FuzzyWordCount(context.Context) int { return 0 } @@ -270,7 +271,7 @@ func (p *nopPage) Lastmod() (t time.Time) { return } -func (p *nopPage) Len() int { +func (p *nopPage) Len(context.Context) int { return 0 } @@ -350,11 +351,11 @@ func (p *nopPage) Permalink() string { return "" } -func (p *nopPage) Plain() string { +func (p *nopPage) Plain(context.Context) string { return "" } -func (p *nopPage) PlainWords() []string { +func (p *nopPage) PlainWords(context.Context) []string { return nil } @@ -386,7 +387,7 @@ func (p *nopPage) RawContent() string { return "" } -func (p *nopPage) ReadingTime() int { +func (p *nopPage) ReadingTime(context.Context) int { return 0 } @@ -402,11 +403,11 @@ func (p *nopPage) RelRef(argsm map[string]interface{}) (string, error) { return "", nil } -func (p *nopPage) Render(layout ...string) (template.HTML, error) { +func (p *nopPage) Render(ctx context.Context, layout ...string) (template.HTML, error) { return "", nil } -func (p *nopPage) RenderString(args ...interface{}) (template.HTML, error) { +func (p *nopPage) RenderString(ctx context.Context, args ...interface{}) (template.HTML, error) { return "", nil } @@ -462,11 +463,11 @@ func (p *nopPage) String() string { return "nopPage" } -func (p *nopPage) Summary() template.HTML { +func (p *nopPage) Summary(context.Context) template.HTML { return "" } -func (p *nopPage) TableOfContents() template.HTML { +func (p *nopPage) TableOfContents(context.Context) template.HTML { return "" } @@ -486,7 +487,7 @@ func (p *nopPage) Translations() Pages { return nil } -func (p *nopPage) Truncated() bool { +func (p *nopPage) Truncated(context.Context) bool { return false } @@ -506,7 +507,7 @@ func (p *nopPage) Weight() int { return 0 } -func (p *nopPage) WordCount() int { +func (p *nopPage) WordCount(context.Context) int { return 0 } diff --git a/tpl/cast/init.go b/tpl/cast/init.go index 079be471995..f132450b4a1 100644 --- a/tpl/cast/init.go +++ b/tpl/cast/init.go @@ -14,6 +14,8 @@ package cast import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.ToInt, diff --git a/tpl/collections/init.go b/tpl/collections/init.go index dc4e1ff3183..4e97d94252f 100644 --- a/tpl/collections/init.go +++ b/tpl/collections/init.go @@ -14,6 +14,8 @@ package collections import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.After, diff --git a/tpl/compare/init.go b/tpl/compare/init.go index f423f615e06..9d64e885d56 100644 --- a/tpl/compare/init.go +++ b/tpl/compare/init.go @@ -14,6 +14,8 @@ package compare import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Default, diff --git a/tpl/crypto/init.go b/tpl/crypto/init.go index 5ce2a4b5e2f..e249b836437 100644 --- a/tpl/crypto/init.go +++ b/tpl/crypto/init.go @@ -14,6 +14,8 @@ package crypto import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.MD5, diff --git a/tpl/data/init.go b/tpl/data/init.go index 5ac24eaabe3..bb1e6c9e9c2 100644 --- a/tpl/data/init.go +++ b/tpl/data/init.go @@ -14,6 +14,8 @@ package data import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.GetCSV, diff --git a/tpl/debug/init.go b/tpl/debug/init.go index 1f032ce69f7..773d0773f56 100644 --- a/tpl/debug/init.go +++ b/tpl/debug/init.go @@ -14,6 +14,8 @@ package debug import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Dump, diff --git a/tpl/diagrams/init.go b/tpl/diagrams/init.go index 1a55788376b..7043c5fb8e8 100644 --- a/tpl/diagrams/init.go +++ b/tpl/diagrams/init.go @@ -14,6 +14,8 @@ package diagrams import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -22,13 +24,13 @@ const name = "diagrams" func init() { f := func(d *deps.Deps) *internal.TemplateFuncsNamespace { - ctx := &Diagrams{ + diag := &Diagrams{ d: d, } ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(ctx context.Context, args ...interface{}) (interface{}, error) { return diag, nil }, } return ns diff --git a/tpl/encoding/init.go b/tpl/encoding/init.go index 77c9c8c494c..f39658a5e7b 100644 --- a/tpl/encoding/init.go +++ b/tpl/encoding/init.go @@ -14,6 +14,8 @@ package encoding import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -22,14 +24,14 @@ const name = "encoding" func init() { f := func(d *deps.Deps) *internal.TemplateFuncsNamespace { - ctx := New() + ec := New() ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(ctx context.Context, args ...interface{}) (interface{}, error) { return ec, nil }, } - ns.AddMethodMapping(ctx.Base64Decode, + ns.AddMethodMapping(ec.Base64Decode, []string{"base64Decode"}, [][2]string{ {`{{ "SGVsbG8gd29ybGQ=" | base64Decode }}`, `Hello world`}, @@ -37,14 +39,14 @@ func init() { }, ) - ns.AddMethodMapping(ctx.Base64Encode, + ns.AddMethodMapping(ec.Base64Encode, []string{"base64Encode"}, [][2]string{ {`{{ "Hello world" | base64Encode }}`, `SGVsbG8gd29ybGQ=`}, }, ) - ns.AddMethodMapping(ctx.Jsonify, + ns.AddMethodMapping(ec.Jsonify, []string{"jsonify"}, [][2]string{ {`{{ (slice "A" "B" "C") | jsonify }}`, `["A","B","C"]`}, diff --git a/tpl/fmt/init.go b/tpl/fmt/init.go index c02f985be64..85b6dc0e78e 100644 --- a/tpl/fmt/init.go +++ b/tpl/fmt/init.go @@ -14,6 +14,8 @@ package fmt import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Print, diff --git a/tpl/hugo/init.go b/tpl/hugo/init.go index f2c43893ef4..f24903ab052 100644 --- a/tpl/hugo/init.go +++ b/tpl/hugo/init.go @@ -15,6 +15,8 @@ package hugo import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -27,7 +29,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return h, nil }, + Context: func(ctx context.Context, args ...interface{}) (interface{}, error) { return h, nil }, } // We just add the Hugo struct as the namespace here. No method mappings. diff --git a/tpl/images/init.go b/tpl/images/init.go index f3233f6e92b..2546fa39141 100644 --- a/tpl/images/init.go +++ b/tpl/images/init.go @@ -14,6 +14,8 @@ package images import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Config, diff --git a/tpl/inflect/init.go b/tpl/inflect/init.go index 5488274654d..516e79eb975 100644 --- a/tpl/inflect/init.go +++ b/tpl/inflect/init.go @@ -14,6 +14,8 @@ package inflect import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Humanize, diff --git a/tpl/internal/templatefuncsRegistry.go b/tpl/internal/templatefuncsRegistry.go index df300a5bb36..b3f07f42a6d 100644 --- a/tpl/internal/templatefuncsRegistry.go +++ b/tpl/internal/templatefuncsRegistry.go @@ -17,6 +17,7 @@ package internal import ( "bytes" + "context" "encoding/json" "fmt" "go/doc" @@ -49,7 +50,7 @@ type TemplateFuncsNamespace struct { Name string // This is the method receiver. - Context func(v ...interface{}) (interface{}, error) + Context func(ctx context.Context, v ...interface{}) (interface{}, error) // Additional info, aliases and examples, per method name. MethodMappings map[string]TemplateFuncMethodMapping @@ -172,7 +173,7 @@ func (t *TemplateFuncsNamespace) toJSON() ([]byte, error) { buf.WriteString(fmt.Sprintf(`%q: {`, t.Name)) - ctx, err := t.Context() + ctx, err := t.Context(context.Background()) if err != nil { return nil, err } diff --git a/tpl/js/init.go b/tpl/js/init.go index 4ab8671cc71..4f04f949179 100644 --- a/tpl/js/init.go +++ b/tpl/js/init.go @@ -14,6 +14,8 @@ package js import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -22,11 +24,11 @@ const name = "js" func init() { f := func(d *deps.Deps) *internal.TemplateFuncsNamespace { - ctx := New(d) + j := New(d) ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(ctx context.Context, args ...interface{}) (interface{}, error) { return j, nil }, } return ns diff --git a/tpl/lang/init.go b/tpl/lang/init.go index f74b6fc3536..188afadab04 100644 --- a/tpl/lang/init.go +++ b/tpl/lang/init.go @@ -14,6 +14,8 @@ package lang import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/langs" "github.com/gohugoio/hugo/tpl/internal" @@ -27,7 +29,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Translate, diff --git a/tpl/math/init.go b/tpl/math/init.go index 32315d3622a..fe27ec7197c 100644 --- a/tpl/math/init.go +++ b/tpl/math/init.go @@ -14,6 +14,8 @@ package math import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Add, diff --git a/tpl/openapi/openapi3/init.go b/tpl/openapi/openapi3/init.go index a0084d503fa..eb5558eb982 100644 --- a/tpl/openapi/openapi3/init.go +++ b/tpl/openapi/openapi3/init.go @@ -14,6 +14,8 @@ package openapi3 import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Unmarshal, diff --git a/tpl/os/init.go b/tpl/os/init.go index c25d63d561f..f785a00d6a1 100644 --- a/tpl/os/init.go +++ b/tpl/os/init.go @@ -14,6 +14,8 @@ package os import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Getenv, diff --git a/tpl/page/init.go b/tpl/page/init.go new file mode 100644 index 00000000000..fc6c72e753a --- /dev/null +++ b/tpl/page/init.go @@ -0,0 +1,55 @@ +// Copyright 2022 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 page provides template functions for accessing the current Page object, +// the entry level context for the current template. +package page + +import ( + "context" + + "github.com/gohugoio/hugo/deps" + "github.com/gohugoio/hugo/resources/page" + "github.com/gohugoio/hugo/tpl" + + "github.com/gohugoio/hugo/tpl/internal" +) + +const name = "page" + +func init() { + f := func(d *deps.Deps) *internal.TemplateFuncsNamespace { + ns := &internal.TemplateFuncsNamespace{ + Name: name, + Context: func(ctx context.Context, args ...interface{}) (interface{}, error) { + v := tpl.GetDataFromContext(ctx) + if v == nil { + return nil, nil + } + + // There is one case where the context value is not a Page, + // and that is the sitemap context. + // We will eventually fix that. + if p, ok := v.(page.Page); ok { + return p, nil + } + + return nil, nil + }, + } + + return ns + } + + internal.AddTemplateFuncsNamespace(f) +} diff --git a/tpl/page/integration_test.go b/tpl/page/integration_test.go new file mode 100644 index 00000000000..262e3a7b47b --- /dev/null +++ b/tpl/page/integration_test.go @@ -0,0 +1,96 @@ +// Copyright 2022 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 page_test + +import ( + "strings" + "testing" + + "github.com/gohugoio/hugo/hugolib" +) + +func TestPageGlobal(t *testing.T) { + t.Parallel() + + files := ` +-- config.toml -- +baseURL = 'http://example.com/' +-- content/_index.md -- +--- +title: "Home" +--- +{{< shortcode >}} + +## Heading + +[I'm an inline-style link](https://www.google.com) + +![alt text](https://github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png "Logo Title Text 1") + +$$$bash +echo "hello"; +$$$ + +-- layouts/_default/_markup/render-heading.html -- +{{ if page.IsHome }} +Heading OK. +{{ end }} +-- layouts/_default/_markup/render-image.html -- +{{ if page.IsHome }} +Image OK. +{{ end }} +-- layouts/_default/_markup/render-link.html -- +{{ if page.IsHome }} +Link OK. +{{ end }} +-- layouts/_default/_markup/render-codeblock.html -- +{{ if page.IsHome }} +Codeblock OK. +{{ end }} +-- layouts/index.html -- +{{ if eq page . }} +Page OK. +{{ end }} +{{ .Content }} +partial: {{ partials.Include "foo.html" . }} +-- layouts/partials/foo.html -- +{{ if page.IsHome }} +Partial OK. +{{ end }} +-- layouts/shortcodes/shortcode.html -- +{{ if page.IsHome }} +Shortcode OK. +{{ end }} + ` + + // Fenced code blocks. + files = strings.ReplaceAll(files, "$$$", "```") + + b := hugolib.NewIntegrationTestBuilder( + hugolib.IntegrationTestConfig{ + T: t, + TxtarString: files, + }, + ).Build() + + b.AssertFileContent("public/index.html", ` +Heading OK. +Image OK. +Link OK. +Codeblock OK. +Page OK. +Partial OK. +Shortcode OK. +`) +} diff --git a/tpl/partials/init.go b/tpl/partials/init.go index 1857b167a9e..8039c6a5015 100644 --- a/tpl/partials/init.go +++ b/tpl/partials/init.go @@ -14,6 +14,8 @@ package partials import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: namespaceName, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Include, diff --git a/tpl/path/init.go b/tpl/path/init.go index 07f20d71700..0ea3d21deef 100644 --- a/tpl/path/init.go +++ b/tpl/path/init.go @@ -14,6 +14,7 @@ package path import ( + "context" "fmt" "path/filepath" @@ -29,7 +30,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Split, diff --git a/tpl/reflect/init.go b/tpl/reflect/init.go index 63500a6a45d..562807aa60a 100644 --- a/tpl/reflect/init.go +++ b/tpl/reflect/init.go @@ -15,6 +15,8 @@ package reflect import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -27,7 +29,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.IsMap, diff --git a/tpl/resources/init.go b/tpl/resources/init.go index 4c8dff7bc67..573f0f54faf 100644 --- a/tpl/resources/init.go +++ b/tpl/resources/init.go @@ -14,6 +14,8 @@ package resources import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -30,7 +32,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Get, diff --git a/tpl/safe/init.go b/tpl/safe/init.go index 9fbae404468..784a93c5c22 100644 --- a/tpl/safe/init.go +++ b/tpl/safe/init.go @@ -14,6 +14,8 @@ package safe import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.CSS, diff --git a/tpl/site/init.go b/tpl/site/init.go index a24d28ad6fd..437291aebe5 100644 --- a/tpl/site/init.go +++ b/tpl/site/init.go @@ -15,6 +15,8 @@ package site import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" @@ -27,7 +29,7 @@ func init() { s := d.Site ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return s, nil }, + Context: func(ctx context.Context, args ...interface{}) (interface{}, error) { return s, nil }, } if s == nil { diff --git a/tpl/strings/init.go b/tpl/strings/init.go index 384a5cda7b4..7860c5b5bf6 100644 --- a/tpl/strings/init.go +++ b/tpl/strings/init.go @@ -14,6 +14,8 @@ package strings import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Chomp, diff --git a/tpl/template.go b/tpl/template.go index 1d8c98ded5c..be2b1c4b739 100644 --- a/tpl/template.go +++ b/tpl/template.go @@ -153,6 +153,10 @@ func GetDataFromContext(ctx context.Context) interface{} { return ctx.Value(texttemplate.DataContextKey) } +func SetDataInContext(ctx context.Context, data interface{}) context.Context { + return context.WithValue(ctx, texttemplate.DataContextKey, data) +} + func GetHasLockFromContext(ctx context.Context) bool { if v := ctx.Value(texttemplate.HasLockContextKey); v != nil { return v.(bool) diff --git a/tpl/templates/init.go b/tpl/templates/init.go index 8da8440ae82..f1b7f89253f 100644 --- a/tpl/templates/init.go +++ b/tpl/templates/init.go @@ -14,6 +14,8 @@ package templates import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Exists, diff --git a/tpl/time/init.go b/tpl/time/init.go index 0ef4fcdfd1d..27744f08908 100644 --- a/tpl/time/init.go +++ b/tpl/time/init.go @@ -14,6 +14,7 @@ package time import ( + "context" "errors" "github.com/gohugoio/hugo/deps" @@ -28,11 +29,11 @@ func init() { if d.Language == nil { panic("Language must be set") } - ctx := New(langs.GetTranslator(d.Language), langs.GetLocation(d.Language)) + translator := New(langs.GetTranslator(d.Language), langs.GetLocation(d.Language)) ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { + Context: func(ctx context.Context, args ...interface{}) (interface{}, error) { // Handle overlapping "time" namespace and func. // // If no args are passed to `time`, assume namespace usage and @@ -42,11 +43,11 @@ func init() { switch len(args) { case 0: - return ctx, nil + return translator, nil case 1: - return ctx.AsTime(args[0]) + return translator.AsTime(args[0]) case 2: - return ctx.AsTime(args[0], args[1]) + return translator.AsTime(args[0], args[1]) // 3 or more arguments. Currently not supported. default: @@ -55,33 +56,33 @@ func init() { }, } - ns.AddMethodMapping(ctx.Format, + ns.AddMethodMapping(translator.Format, []string{"dateFormat"}, [][2]string{ {`dateFormat: {{ dateFormat "Monday, Jan 2, 2006" "2015-01-21" }}`, `dateFormat: Wednesday, Jan 21, 2015`}, }, ) - ns.AddMethodMapping(ctx.Now, + ns.AddMethodMapping(translator.Now, []string{"now"}, [][2]string{}, ) - ns.AddMethodMapping(ctx.AsTime, + ns.AddMethodMapping(translator.AsTime, nil, [][2]string{ {`{{ (time "2015-01-21").Year }}`, `2015`}, }, ) - ns.AddMethodMapping(ctx.Duration, + ns.AddMethodMapping(translator.Duration, []string{"duration"}, [][2]string{ {`{{ mul 60 60 | duration "second" }}`, `1h0m0s`}, }, ) - ns.AddMethodMapping(ctx.ParseDuration, + ns.AddMethodMapping(translator.ParseDuration, nil, [][2]string{ {`{{ "1h12m10s" | time.ParseDuration }}`, `1h12m10s`}, diff --git a/tpl/tplimpl/template.go b/tpl/tplimpl/template.go index 70671927812..1a54a7f9403 100644 --- a/tpl/tplimpl/template.go +++ b/tpl/tplimpl/template.go @@ -226,7 +226,8 @@ func (t templateExec) Clone(d *deps.Deps) *templateExec { } func (t *templateExec) Execute(templ tpl.Template, wr io.Writer, data interface{}) error { - return t.ExecuteWithContext(context.Background(), templ, wr, data) + return errors.New("Please use ExecuteWithContext") + // return t.ExecuteWithContext(context.Background(), templ, wr, data) } func (t *templateExec) ExecuteWithContext(ctx context.Context, templ tpl.Template, wr io.Writer, data interface{}) error { diff --git a/tpl/tplimpl/template_funcs.go b/tpl/tplimpl/template_funcs.go index 8692b9ee214..5a11ce65570 100644 --- a/tpl/tplimpl/template_funcs.go +++ b/tpl/tplimpl/template_funcs.go @@ -49,6 +49,7 @@ import ( _ "github.com/gohugoio/hugo/tpl/math" _ "github.com/gohugoio/hugo/tpl/openapi/openapi3" _ "github.com/gohugoio/hugo/tpl/os" + _ "github.com/gohugoio/hugo/tpl/page" _ "github.com/gohugoio/hugo/tpl/partials" _ "github.com/gohugoio/hugo/tpl/path" _ "github.com/gohugoio/hugo/tpl/reflect" diff --git a/tpl/transform/init.go b/tpl/transform/init.go index aa7297bc4e5..cd402da4344 100644 --- a/tpl/transform/init.go +++ b/tpl/transform/init.go @@ -14,6 +14,8 @@ package transform import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Emojify, diff --git a/tpl/transform/transform.go b/tpl/transform/transform.go index dc7cc0342c0..5641a9992ca 100644 --- a/tpl/transform/transform.go +++ b/tpl/transform/transform.go @@ -15,6 +15,7 @@ package transform import ( + "context" "html" "html/template" @@ -112,7 +113,7 @@ func (ns *Namespace) HTMLUnescape(s interface{}) (string, error) { } // Markdownify renders a given input from Markdown to HTML. -func (ns *Namespace) Markdownify(s interface{}) (template.HTML, error) { +func (ns *Namespace) Markdownify(ctx context.Context, s interface{}) (template.HTML, error) { defer herrors.Recover() ss, err := cast.ToStringE(s) if err != nil { @@ -123,7 +124,7 @@ func (ns *Namespace) Markdownify(s interface{}) (template.HTML, error) { if home == nil { panic("home must not be nil") } - sss, err := home.RenderString(ss) + sss, err := home.RenderString(ctx, ss) // Strip if this is a short inline type of text. bb := ns.deps.ContentSpec.TrimShortHTML([]byte(sss)) diff --git a/tpl/urls/init.go b/tpl/urls/init.go index 0a97045e242..03ff456ca4b 100644 --- a/tpl/urls/init.go +++ b/tpl/urls/init.go @@ -14,6 +14,8 @@ package urls import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...interface{}) (interface{}, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...interface{}) (interface{}, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.AbsURL,