diff --git a/hugolib/shortcode.go b/hugolib/shortcode.go index 6d87414a7..cd2f268f1 100644 --- a/hugolib/shortcode.go +++ b/hugolib/shortcode.go @@ -338,14 +338,9 @@ func (s *shortcodeHandler) prepareShortcodeForPage(placeholder string, sc *short if sc.isInline { key := newScKeyFromLangAndOutputFormat(lang, p.outputFormats[0], placeholder) - if !s.enableInlineShortcodes { - m[key] = func() (string, error) { - return "", nil - } - } else { - m[key] = func() (string, error) { - return renderShortcode(key, sc, nil, p) - } + m[key] = func() (string, error) { + return renderShortcode(key, sc, nil, p) + } return m @@ -372,6 +367,9 @@ func renderShortcode( var tmpl tpl.Template if sc.isInline { + if !p.s.enableInlineShortcodes { + return "", nil + } templName := path.Join("_inline_shortcode", p.Path(), sc.name) if sc.isClosing { templStr := sc.innerString() @@ -542,6 +540,10 @@ func (s *shortcodeHandler) contentShortcodesForOutputFormat(f output.Format) *or if !found && key.Suffix != "html" { key.Suffix = "html" renderFn, found = s.contentShortcodes.Get(key) + if !found { + key.OutputFormat = "HTML" + renderFn, found = s.contentShortcodes.Get(key) + } } if !found { diff --git a/hugolib/shortcode_test.go b/hugolib/shortcode_test.go index 9545301ea..16ff0b780 100644 --- a/hugolib/shortcode_test.go +++ b/hugolib/shortcode_test.go @@ -1076,40 +1076,67 @@ enableInlineShortcodes = %t b := newTestSitesBuilder(t) b.WithConfigFile("toml", conf) - b.WithContent("page-md-shortcode.md", `--- -title: "Hugo" ---- -FIRST:{{< myshort.inline "first" >}} + shortcodeContent := `FIRST:{{< myshort.inline "first" >}} Page: {{ .Page.Title }} Seq: {{ seq 3 }} Param: {{ .Get 0 }} {{< /myshort.inline >}}:END: SECOND:{{< myshort.inline "second" />}}:END +NEW INLINE: {{< n1.inline "5" >}}W1: {{ seq (.Get 0) }}{{< /n1.inline >}}:END: +INLINE IN INNER: {{< outer >}}{{< n2.inline >}}W2: {{ seq 4 }}{{< /n2.inline >}}{{< /outer >}}:END: +REUSED INLINE IN INNER: {{< outer >}}{{< n1.inline "3" />}}{{< /outer >}}:END: +` -`) + b.WithContent("page-md-shortcode.md", `--- +title: "Hugo" +--- +`+shortcodeContent) + + b.WithContent("_index.md", `--- +title: "Hugo Home" +--- + +`+shortcodeContent) b.WithTemplatesAdded("layouts/_default/single.html", ` CONTENT:{{ .Content }} `) + b.WithTemplatesAdded("layouts/index.html", ` +CONTENT:{{ .Content }} +`) + + b.WithTemplatesAdded("layouts/shortcodes/outer.html", `Inner: {{ .Inner }}`) + b.CreateSites().Build(BuildCfg{}) + shouldContain := []string{ + "Seq: [1 2 3]", + "Param: first", + "Param: second", + "NEW INLINE: W1: [1 2 3 4 5]", + "INLINE IN INNER: Inner: W2: [1 2 3 4]", + "REUSED INLINE IN INNER: Inner: W1: [1 2 3]", + } + if enableInlineShortcodes { b.AssertFileContent("public/page-md-shortcode/index.html", - "Page: Hugo", - "Seq: [1 2 3]", - "Param: first", - "Param: second", + shouldContain..., + ) + b.AssertFileContent("public/index.html", + shouldContain..., ) } else { b.AssertFileContent("public/page-md-shortcode/index.html", "FIRST::END", "SECOND::END", + "NEW INLINE: :END", + "INLINE IN INNER: Inner: :END:", + "REUSED INLINE IN INNER: Inner: :END:", ) } - }) } diff --git a/parser/pageparser/pagelexer_shortcode.go b/parser/pageparser/pagelexer_shortcode.go index fe182459a..d503d1797 100644 --- a/parser/pageparser/pagelexer_shortcode.go +++ b/parser/pageparser/pagelexer_shortcode.go @@ -280,6 +280,7 @@ func lexInsideShortcode(l *pageLexer) stateFunc { return l.errorf("got closing shortcode, but none is open") } l.closingState++ + l.isInline = false l.emit(tScClose) case r == '\\': l.ignore() diff --git a/parser/pageparser/pageparser_shortcode_test.go b/parser/pageparser/pageparser_shortcode_test.go index dc3af5a01..75ee56090 100644 --- a/parser/pageparser/pageparser_shortcode_test.go +++ b/parser/pageparser/pageparser_shortcode_test.go @@ -24,6 +24,7 @@ var ( tstSCClose = nti(tScClose, "/") tstSC1 = nti(tScName, "sc1") tstSC1Inline = nti(tScNameInline, "sc1.inline") + tstSC2Inline = nti(tScNameInline, "sc2.inline") tstSC2 = nti(tScName, "sc2") tstSC3 = nti(tScName, "sc3") tstSCSlash = nti(tScName, "sc/sub") @@ -152,6 +153,9 @@ var shortCodeLexerTests = []lexerTest{ {"basic inline", `{{< sc1.inline >}}Hello World{{< /sc1.inline >}}`, []Item{tstLeftNoMD, tstSC1Inline, tstRightNoMD, tstText, tstLeftNoMD, tstSCClose, tstSC1Inline, tstRightNoMD, tstEOF}}, {"basic inline with space", `{{< sc1.inline >}}Hello World{{< / sc1.inline >}}`, []Item{tstLeftNoMD, tstSC1Inline, tstRightNoMD, tstText, tstLeftNoMD, tstSCClose, tstSC1Inline, tstRightNoMD, tstEOF}}, {"inline self closing", `{{< sc1.inline >}}Hello World{{< /sc1.inline >}}Hello World{{< sc1.inline />}}`, []Item{tstLeftNoMD, tstSC1Inline, tstRightNoMD, tstText, tstLeftNoMD, tstSCClose, tstSC1Inline, tstRightNoMD, tstText, tstLeftNoMD, tstSC1Inline, tstSCClose, tstRightNoMD, tstEOF}}, + {"inline self closing, then a new inline", `{{< sc1.inline >}}Hello World{{< /sc1.inline >}}Hello World{{< sc1.inline />}}{{< sc2.inline >}}Hello World{{< /sc2.inline >}}`, []Item{ + tstLeftNoMD, tstSC1Inline, tstRightNoMD, tstText, tstLeftNoMD, tstSCClose, tstSC1Inline, tstRightNoMD, tstText, tstLeftNoMD, tstSC1Inline, tstSCClose, tstRightNoMD, + tstLeftNoMD, tstSC2Inline, tstRightNoMD, tstText, tstLeftNoMD, tstSCClose, tstSC2Inline, tstRightNoMD, tstEOF}}, {"inline with template syntax", `{{< sc1.inline >}}{{ .Get 0 }}{{ .Get 1 }}{{< /sc1.inline >}}`, []Item{tstLeftNoMD, tstSC1Inline, tstRightNoMD, nti(tText, "{{ .Get 0 }}"), nti(tText, "{{ .Get 1 }}"), tstLeftNoMD, tstSCClose, tstSC1Inline, tstRightNoMD, tstEOF}}, {"inline with nested shortcode (not supported)", `{{< sc1.inline >}}Hello World{{< sc1 >}}{{< /sc1.inline >}}`, []Item{tstLeftNoMD, tstSC1Inline, tstRightNoMD, tstText, nti(tError, "inline shortcodes do not support nesting")}}, {"inline case mismatch", `{{< sc1.Inline >}}Hello World{{< /sc1.Inline >}}`, []Item{tstLeftNoMD, nti(tError, "period in shortcode name only allowed for inline identifiers")}}, @@ -160,10 +164,12 @@ var shortCodeLexerTests = []lexerTest{ func TestShortcodeLexer(t *testing.T) { t.Parallel() for i, test := range shortCodeLexerTests { - items := collect([]byte(test.input), true, lexMainSection) - if !equal(items, test.items) { - t.Errorf("[%d] %s: got\n\t%v\nexpected\n\t%v", i, test.name, items, test.items) - } + t.Run(test.name, func(t *testing.T) { + items := collect([]byte(test.input), true, lexMainSection) + if !equal(items, test.items) { + t.Errorf("[%d] %s: got\n\t%v\nexpected\n\t%v", i, test.name, items, test.items) + } + }) } } diff --git a/tpl/tplimpl/template.go b/tpl/tplimpl/template.go index 144bafdd8..8efeb6ce9 100644 --- a/tpl/tplimpl/template.go +++ b/tpl/tplimpl/template.go @@ -366,7 +366,8 @@ func (t *htmlTemplates) addLateTemplate(name, tpl string) error { } type textTemplate struct { - t *texttemplate.Template + mu sync.RWMutex + t *texttemplate.Template } func (t *textTemplate) Parse(name, tpl string) (tpl.Template, error) { @@ -374,11 +375,17 @@ func (t *textTemplate) Parse(name, tpl string) (tpl.Template, error) { } func (t *textTemplate) Lookup(name string) (tpl.Template, bool) { + t.mu.RLock() + defer t.mu.RUnlock() + tpl := t.t.Lookup(name) return tpl, tpl != nil } func (t *textTemplate) parSeIn(tt *texttemplate.Template, name, tpl string) (*texttemplate.Template, error) { + t.mu.Lock() + defer t.mu.Unlock() + templ, err := tt.New(name).Parse(tpl) if err != nil { return nil, err