diff --git a/docs/content/extras/shortcodes.md b/docs/content/extras/shortcodes.md index ecb087082e9..79c6871cd0a 100644 --- a/docs/content/extras/shortcodes.md +++ b/docs/content/extras/shortcodes.md @@ -193,6 +193,10 @@ of the content between the opening and closing shortcodes. If a closing shortcode is required, you can check the length of `.Inner` and provide a warning to the user. +A shortcode with `.Inner` content can be used wihout the inline content, and without the closing shortcode, by using the self-closing syntax: + + {{}} + The variable `.Params` contains the list of parameters in case you need to do more complicated things than `.Get`. You can also use the variable `.Page` to access all the normal [Page Variables](/templates/variables/). diff --git a/hugolib/shortcode.go b/hugolib/shortcode.go index f144fa38bac..08a48d98b2b 100644 --- a/hugolib/shortcode.go +++ b/hugolib/shortcode.go @@ -307,15 +307,21 @@ Loop: } case tScClose: + next := pt.peek() if !isInner { - next := pt.peek() if next.typ == tError { // return that error, more specific continue } return sc, fmt.Errorf("Shortcode '%s' in page '%s' has no .Inner, yet a closing tag was provided", next.val, p.FullFilePath()) } - pt.consume(2) + if next.typ == tRightDelimScWithMarkup || next.typ == tRightDelimScNoMarkup { + // self-closing + pt.consume(1) + } else { + pt.consume(2) + } + return sc, nil case tText: sc.inner = append(sc.inner, currItem.val) diff --git a/hugolib/shortcode_test.go b/hugolib/shortcode_test.go index 5431e1cf419..ad1bd3ac850 100644 --- a/hugolib/shortcode_test.go +++ b/hugolib/shortcode_test.go @@ -184,6 +184,9 @@ func TestExtractShortcodes(t *testing.T) { testScPlaceholderRegexp, ""}, {"inner", `Some text. {{< inner >}}Inner Content{{< / inner >}}. Some more text.`, `inner([], false){[Inner Content]}`, fmt.Sprintf("Some text. %s. Some more text.", testScPlaceholderRegexp), ""}, + // issue #934 + {"inner self-closing", `Some text. {{< inner />}}. Some more text.`, `inner([], false){[]}`, + fmt.Sprintf("Some text. %s. Some more text.", testScPlaceholderRegexp), ""}, {"close, but not inner", "{{< tag >}}foo{{< /tag >}}", "", false, "Shortcode 'tag' in page 'simple.md' has no .Inner.*"}, {"nested inner", `Inner->{{< inner >}}Inner Content->{{% inner2 param1 %}}inner2txt{{% /inner2 %}}Inner close->{{< / inner >}}<-done`, `inner([], false){[Inner Content-> inner2([\"param1\"], true){[inner2txt]} Inner close->]}`, @@ -212,7 +215,7 @@ func TestExtractShortcodes(t *testing.T) { tem.AddInternalShortcode("tag.html", `tag`) tem.AddInternalShortcode("sc1.html", `sc1`) tem.AddInternalShortcode("sc2.html", `sc2`) - tem.AddInternalShortcode("inner.html", `{{.Inner}}`) + tem.AddInternalShortcode("inner.html", `{{with .Inner }}{{ . }}{{ end }}`) tem.AddInternalShortcode("inner2.html", `{{.Inner}}`) tem.AddInternalShortcode("inner3.html", `{{.Inner}}`) diff --git a/hugolib/shortcodeparser_test.go b/hugolib/shortcodeparser_test.go index 8fa02448a88..4485fa13029 100644 --- a/hugolib/shortcodeparser_test.go +++ b/hugolib/shortcodeparser_test.go @@ -65,6 +65,9 @@ var shortCodeLexerTests = []shortCodeLexerTest{ {"two params", `{{< sc1 param1 param2 >}}`, []item{ tstLeftNoMD, tstSC1, tstParam1, tstParam2, tstRightNoMD, tstEOF}}, + // issue #934 + {"self-closing", `{{< sc1 />}}`, []item{ + tstLeftNoMD, tstSC1, tstSCClose, tstRightNoMD, tstEOF}}, {"nested simple", `{{< sc1 >}}{{< sc2 >}}{{< /sc1 >}}`, []item{ tstLeftNoMD, tstSC1, tstRightNoMD, tstLeftNoMD, tstSC2, tstRightNoMD,