Make Partials accepts both dot context only and with extra parameters

I have a partial, it’s called feature section, it outputs a html structure of feature section with provided data.

normally i will hardcoded the reference of the data inside the partials eg. .Site.Data.feature_default then call the partial:

{{ partial "featureSection.html" .  }}

Now, i want to show feature section again in the same layout template. But, i realized this is not possible, because i want to use different data from .Site.data.feature_custom.

Of course, i need to modify partial to accept custom context and extra parameters

{{ partial "featureSection.html" (dict "ctx" . "data" .Site.Data.feature_custom) }}

But after the modification, i can’t pass the dot context directly, because the dot context already remapped to .ctx

The solution is to make partials accept both dot context only and custom context plus extra parameters.

The goal of this tutorial, we can use the partial in two way:

The Default, by passing the dot context only

{{ partial "featureSection.html" .  }}

Custom Usage, by passing remapped dot context and add extra parameters

{​{ partial "featureSection.html" (dict "ctx" . "data" .Site.Data.feature_custom) }​}

Now, lets prepare our partial: partials/featureSection.html

{{- /* 

  Prepare the Variables, 

  set the value to `nil` with the help of `default` function
  Why using`nil`? 
  `nil` is not ouputting anything and comparable using `not`

  $ctx always overidden in both cases, you can set anything you want

*/ -}}

{{- $ctx := "" -}}
{{- $data := default nil -}}
{{- $id := default nil -}}

{{- if (reflect.IsMap . ) -}}
  
  {{- /* Assign Custom Context */ -}}
  {{- $ctx = .ctx -}}
  
  {{- /* Assign value of .data */ -}}
  {{- $data = cond (not .data) nil .data -}}
  
  {{- /* Assign value of .id */ -}}
  {{- $id = cond (not .id) nil .id  -}}

{{- else -}}

  {{- /* Passing dot context, default behaviour */ -}}
  {{- $ctx = . -}}
  
  {{- /* Default Data for Dot Context */ -}}
  {{- $data = .Site.Data.feature_default -}}
  
{{- end -}}



{{/* Check if $data is available */}}
{{ if $data }}
<ul class="feature-list {{ $id }}">
  {{ range $name := $data.list }}
    <li>{{ .name }}, {{ .message }}</li> 
  {{ end }}
</ul>  
{{ end }}

Done, now you can call your partial in two way

A Repository to test this tricks: hugo-snippets/hugo-adaptive-partial

3 Likes