Nested Shortcodes - Closest Parent Parameter

Below is a partial to be used with a shortcode template to retrieve the closest parameter. First checking itself then looping through parents until it finds a match. If no match is found it returns false. The partial sets a scratch variable as it’s output, instructions in file.

Also here is a link to the inverse, Furthest/Farthest Parent Param.

– START PARTIAL –

{{/* 

  The following partial/function looks for the closest parent parameter in nested shortcodes. It will also check itself. It then retrieves
  it and sets it to a scratch variable with the same name as the file name minus "return--". That variable is then populated 
  and available after the call to the partial.

  EXAMPLE SHORTCODE STRUCTURE:
  {{< parent >}}
    {{< subParent title="Hello World 2">}}
      {{< child >}}
    {{< /subParent >}}
  {{< /parent >}}

  USAGE (inside child shortcode):
  {{ $var := $.Page.Scratch }}
  {{ partial "return--parentParamClosest.html" (dict "current" . "parameterKey" "title") }}
  {{ $parentTitle := $var.Get "parentParamClosest" }}

  PARAMETERS:           dict        (current, parameterKey) 
  - current             context     current shortcode scope/context (ie ".")
  - parameterKey        string      Shortcode parameter key

  RETURNS: 
  - False if no parameter is found

*/}}

{{ $var := .current.Page.Scratch }}
{{ $param := .current.Get .parameterKey }}
{{ $var.Set "parentParamClosest" false }}
{{ $var.Set "parentParameterFound" false }}

<!-- Since this is closest we look first then check for parents -->
{{ if and $param (ne ($var.Get "parentParameterFound") true) }}
  {{ $var.Set "parentParameterFound" true }}
  {{ $var.Set "parentParamClosest" $param }}
{{ end }}

<!-- First Checking if shortcode has a parent -->
{{ if and .current.Parent (ne ($var.Get "parentParameterFound") true) }}
  {{ partial "fn/return--parentParamClosest.html" (dict "current" .current.Parent "parameterKey" .parameterKey) }}
{{ end }}
1 Like

Hi, total noob here… @Scherb I was wondering if you could explain or point me somewhere that explains how to use your code exactly. You call this a partial, but all I find are template partials… is this a shortcode by itself? Or what? Thanks

Hi Nando,

Partials can be used within shortcodes. Save the partial above in the partials folder. Then to use call the partial passing it the context (".") and the parameter to search for… In the example below I am searching for the closest parent parameter called “title”. The partial will save the parameter (if found) into Scratch. Calling Scratch.Get “parentParamClosest” will give you the parameters value (if found) or false if not found.

About the DICT:
The dict function in the parameter is a way of sending multiple parameters to a partial using an object (key/value pair, space separated). We are sending it two values “current” which is the context “.” and the parameterKey which is the parameter you are searching for. Most of the time you don’t need to change the “current” . part unless your scope is changed (inside a range).

Please let me know if this was helpful.

Below is an example for getting the closest parent shortcode with the parameter of “title”:

<!-- You call the partial with the desired "parameterKey" -->
{{ partial "return--parentParamClosest.html" (dict "current" . "parameterKey" "title") }}

<!-- The partial stores the value in scratch which we save below in the variable-->
{{ $title := $.Page.Scratch.Get "parentParamClosest" }}

<!-- Which can be used in your template like so -->
{{ with $title }}
  <h2>{{ . }}</h2>
{{ end}}
1 Like

Hi Nando,

@nando
There is a mistake in my code based on my own environment. Please use the code below which assumes this code would be saved in the /layouts/partials/. It was in a subdirectory before (sorry). I wrote instructions in the post above.

{{/* 

  The following partial/function looks for the closest parent parameter in nested shortcodes. It will also check itself. It then retrieves
  it and sets it to a scratch variable with the same name as the file name minus "return--". That variable is then populated 
  and available after the call to the partial.

  EXAMPLE SHORTCODE STRUCTURE:
  {{< parent >}}
    {{< subParent title="Hello World 2">}}
      {{< child >}}
    {{< /subParent >}}
  {{< /parent >}}

  USAGE (inside child shortcode):
  {{ $var := $.Page.Scratch }}
  {{ partial "return--parentParamClosest.html" (dict "current" . "parameterKey" "title") }}
  {{ $parentTitle := $var.Get "parentParamClosest" }}

  PARAMETERS:           dict        (current, parameterKey) 
  - current             context     current shortcode scope/context (ie ".")
  - parameterKey        string      Shortcode parameter key

  RETURNS: 
  - False if no parameter is found

*/}}

{{ $var := .current.Page.Scratch }}
{{ $param := .current.Get .parameterKey }}
{{ $var.Set "parentParamClosest" false }}
{{ $var.Set "parentParameterFound" false }}

<!-- Since this is closest we look first then check for parents -->
{{ if and $param (ne ($var.Get "parentParameterFound") true) }}
  {{ $var.Set "parentParameterFound" true }}
  {{ $var.Set "parentParamClosest" $param }}
{{ end }}

<!-- First Checking if shortcode has a parent -->
{{ if and .current.Parent (ne ($var.Get "parentParameterFound") true) }}
  {{ partial "return--parentParamClosest.html" (dict "current" .current.Parent "parameterKey" .parameterKey) }}
{{ end }}
1 Like

thank you SO much for this! was very detailed and helpful. I’ll give this a try and give you more feedback in a bit.

YES IT WORKS! I’ve been looking for this solution for weeks, truly appreciated.
One thing I’d like to add for other beginners: the partial should be saved as return--parentParamClosest.html in your partials folder. This is probably obvious to more advanced users, but with this info it becomes usable to everyone :slight_smile: