Error saying varible is not defined

Hi there! I’m quite new to hugo, so excuse me for missing something obvious.
I want to set a varible called ‘title’ to title | site-title if page.title exists, or site-title if it doesn’t. I’ve got that far.

<title>{{ if .Title }}{{ .Title }} | {{ end }}{{ .Site.Title }}</title>

However, I’d rather not repeat myself, so I found out how to do it as a varible.

{{ $title := .Site.Title }}
{{ if .Title }}
{{ $title = printf "%s%s%s" .Title " | " .Site.Title }}
{{ end }}

However, later on in the template, I have this.

<title>{{ $title }}</title>
{{ block "opengraph" . }}
  <meta property="og:title" content="{{ $title }}" />
  <meta property="og:description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end }}" />
{{ end }}

<title>{{ $title }}</title> renders fine, but 2 lines later, hugo explodes:

Error: parse failed: template: partials/social-tags.html:10: undefined variable "$title"

FYI, line 10 is the 3rd line down on the code block above:

  <meta property="og:title" content="{{ $title }}" />

I’ve looked around, and the best I’ve found is this:


That effectively says that it’s impossible to fix in pure go templates.
Some help?

You variables are limited to your template scope. The block “opengraph” is another template and cannot use this one’s variables.

Just like with a partial, you could pass a map as context to your block:

{{ block "opengraph" (dict "Page" . "title" $title) }}
  <meta property="og:title" content="{{ .title }}" />
  <meta property="og:description" content="{{ with .Page.Description }}{{ . }}{{ else }}{{if .Page.IsPage}}{{ .Page.Summary }}{{ else }}{{ with .Page.Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end }}" />
{{ end }}

Or, you could attach your title to the page’s scratch before passing it to the template as context.

{{ .Scratch.Set "title" $title }}
{{ block "opengraph" . }}
  <meta property="og:title" content="{{ .Scratch.Get "title" }}" />
  <meta property="og:description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end }}" />
{{ end }}

I prefer the second one for clarity/cleanliness.

Utlimately, I would drop all heavy logic of meta tags into one single template shared by all.