hugo

Unnamed repository; edit this file 'description' to name the repository.

git clone git://git.shimmy1996.com/hugo.git
commit 9896cd0030da75bf6acab14dad0a7f78472ceff9
parent 866176be971c460d05a7b3b09b1034eb9a25ec56
Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Date:   Tue,  8 Mar 2016 20:56:24 +0100

Add reference to parent shortcode

Fixes #1936

Diffstat:
Mdocs/content/extras/shortcodes.md | 2++
Mhugolib/shortcode.go | 9+++++----
Mhugolib/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
@@ -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
 
     {{</* youtube 09jf3ow9jfw */>}}
diff --git 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<p>(.*)</p>\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
@@ -232,6 +232,17 @@ func TestNestedComplexSC(t *testing.T) {
 		"-row-1-s-col-2-<strong>s</strong>-aside-3-<strong>s</strong>-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<figure class=\"bananas orange\">\n    \n        <img src=\"/found/here\" alt=\"apple\" width=\"100px\" />\n    \n    \n</figure>\n", tem)