Fix some inline shortcode issues
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Thu, 31 Jan 2019 10:53:21 +0000 (11:53 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Thu, 31 Jan 2019 18:08:19 +0000 (19:08 +0100)
Fixes #5645
Fixes #5653

hugolib/shortcode.go
hugolib/shortcode_test.go
parser/pageparser/pagelexer_shortcode.go
parser/pageparser/pageparser_shortcode_test.go
tpl/tplimpl/template.go

index 6d87414a7fee5a6fdcf040113ca8b944d62968ff..cd2f268f1233abdf52b1c7dd0fa637226214a12b 100644 (file)
@@ -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 {
index 9545301ea8014bf5dab4768ea2d5245ece99b772..16ff0b7806b5c07e3180ca253c3e46cebb32239e 100644 (file)
@@ -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:",
                                        )
                                }
-
                        })
 
        }
index fe182459a54ada47fa6e569511771714f88f7720..d503d1797ee8050cfe0b98975098287575ad4298 100644 (file)
@@ -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()
index dc3af5a01dab9c4c4cbefdf751985159d2787acc..75ee560906864e9d1221b3fba5d2c645683468e0 100644 (file)
@@ -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)
+                       }
+               })
        }
 }
 
index 144bafdd8d819161609454650b5b7458fbe5dea0..8efeb6ce959a96140ce1cb8938d8b74ee9eca1c3 100644 (file)
@@ -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