From 9896cd0030da75bf6acab14dad0a7f78472ceff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Tue, 8 Mar 2016 20:56:24 +0100 Subject: [PATCH] Add reference to parent shortcode Fixes #1936 --- docs/content/extras/shortcodes.md | 2 ++ hugolib/shortcode.go | 9 +++++---- hugolib/shortcode_test.go | 11 +++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/docs/content/extras/shortcodes.md b/docs/content/extras/shortcodes.md index ef78b30c9..34c6f3486 100644 --- a/docs/content/extras/shortcodes.md +++ b/docs/content/extras/shortcodes.md @@ -273,6 +273,8 @@ such as `{{ if .IsNamedParams }}...{{ else }}...{{ end }}`. See the You can also use the variable `.Page` to access all the normal [Page Variables](/templates/variables/). +A shortcodes can be nested. In a nested shortcode you can access the parent shortcode context with `.Parent`. This can be very useful for inheritance of common shortcode parameters from the root. + ## Single Positional Example: youtube {{}} diff --git a/hugolib/shortcode.go b/hugolib/shortcode.go index 4cd1db87b..578093210 100644 --- a/hugolib/shortcode.go +++ b/hugolib/shortcode.go @@ -34,6 +34,7 @@ type ShortcodeWithPage struct { Params interface{} Inner template.HTML Page *Page + Parent *ShortcodeWithPage IsNamedParams bool } @@ -189,7 +190,7 @@ const innerNewlineRegexp = "\n" const innerCleanupRegexp = `\A

(.*)

\n\z` const innerCleanupExpand = "$1" -func renderShortcode(sc shortcode, p *Page, t tpl.Template) string { +func renderShortcode(sc shortcode, parent *ShortcodeWithPage, p *Page, t tpl.Template) string { tmpl := getShortcodeTemplate(sc.name, t) if tmpl == nil { @@ -197,7 +198,7 @@ func renderShortcode(sc shortcode, p *Page, t tpl.Template) string { return "" } - data := &ShortcodeWithPage{Params: sc.params, Page: p} + data := &ShortcodeWithPage{Params: sc.params, Page: p, Parent: parent} if sc.params != nil { data.IsNamedParams = reflect.TypeOf(sc.params).Kind() == reflect.Map } @@ -209,7 +210,7 @@ func renderShortcode(sc shortcode, p *Page, t tpl.Template) string { case string: inner += innerData.(string) case shortcode: - inner += renderShortcode(innerData.(shortcode), p, t) + inner += renderShortcode(innerData.(shortcode), data, p, t) default: jww.ERROR.Printf("Illegal state on shortcode rendering of '%s' in page %s. Illegal type in inner data: %s ", sc.name, p.BaseFileName(), reflect.TypeOf(innerData)) @@ -271,7 +272,7 @@ func extractAndRenderShortcodes(stringToParse string, p *Page, t tpl.Template) ( // need to have something to replace with renderedShortcodes[key] = "" } else { - renderedShortcodes[key] = renderShortcode(sc, p, t) + renderedShortcodes[key] = renderShortcode(sc, nil, p, t) } } diff --git a/hugolib/shortcode_test.go b/hugolib/shortcode_test.go index 26854562e..306b53e84 100644 --- a/hugolib/shortcode_test.go +++ b/hugolib/shortcode_test.go @@ -232,6 +232,17 @@ func TestNestedComplexSC(t *testing.T) { "-row-1-s-col-2-s-aside-3-s-asideStop-4-s-colStop-5-s-rowStop-6-s", tem) } +func TestParentShortcode(t *testing.T) { + tem := tpl.New() + tem.AddInternalShortcode("r1.html", `1: {{ .Get "pr1" }} {{ .Inner }}`) + tem.AddInternalShortcode("r2.html", `2: {{ .Parent.Get "pr1" }}{{ .Get "pr2" }} {{ .Inner }}`) + tem.AddInternalShortcode("r3.html", `3: {{ .Parent.Parent.Get "pr1" }}{{ .Parent.Get "pr2" }}{{ .Get "pr3" }} {{ .Inner }}`) + + CheckShortCodeMatch(t, `{{< r1 pr1="p1" >}}1: {{< r2 pr2="p2" >}}2: {{< r3 pr3="p3" >}}{{< /r3 >}}{{< /r2 >}}{{< /r1 >}}`, + "1: p1 1: 2: p1p2 2: 3: p1p2p3 ", tem) + +} + func TestFigureImgWidth(t *testing.T) { tem := tpl.New() CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" alt="apple" width="100px" %}}`, "\n
\n \n \"apple\"\n \n \n
\n", tem)