Conditionally include some text in markdown file

Hard thing to find since it uses so many generic terms. Basically - at a high-level - I want to be able to include/exclude parts of a manual depending on what type of build I’m putting together (full/demo/educational/etc.).

This is what I’m trying to do:

  1. pass a variable on the command line - e.g. “FOO=bar”
  2. in my markdown file (not my templates) I want to use FOO to conditionally include some text. Something like:
{{ if eq FOO bar }}
show this text
{{ end }}

I have found I can do this on the command line:

export FOO=bar && hugo ....

But then I can only use {{ if eq (getenv "FOO") "bar" }} in templates, not in my markdown files.

Is there a clean way to do this? I feel like I’m missing something obvious since this must be a common use-case.

Thanks!

This is not a common use case that I know of. But you have me curious…

So, when you find yourself wanting to use templating in your markdown file, then it’s time to make a shortcode.

Below is a minimum reproducible example.

The toggler shortcode accepts two arguments: the env var name, and the env var value.

Markdown File

Always show me.

{{< toggler "NAME" "Zach" >}}
Only show me when NAME=Zach
{{< /toggler >}}

{{< toggler "NAME" "Jane" >}}
Only show me when NAME=Jane
{{< /toggler >}}

Shortcode File

It’s relative path is layouts/shortcodes/toggler.html

{{ $name := .Get 0 }}
{{ $value := .Get 1 }}
{{ $result := getenv $name }}
{{ if eq $result $value }}
{{ .Inner }}
{{ end }}

Output

When you run hugo

<p>Always show me.</p>

When you run NAME=Zach hugo

<p>Always show me.</p>
Only show me when NAME=Zach

When you run NAME=Jane hugo

<p>Always show me.</p>
Only show me when NAME=Jane

This is fantastic. Thank you @zwbetz !

I created two versions if_eq and if_ne, so now I can do this:

{{< if_eq BUILD "full" >}}
This is the full build.
{{< /if_eq >}}

{{< if_ne BUILD "demo" >}}
This is not the demo.
{{< /if_ne >}}

I can get by with just these, but is there a way to capture an else statement? Something like:

{{< if_eq BUILD "demo" >}}
This is the demo build.
{{< else >}}
This is all other build types.
{{< /if_eq >}}

Good deal.

Not that I know of.

Technically speaking: if_eq as a shortcode should be able to handle ne if_eq too. If you post your shortcodes someone will be able to add a “else” option to it. It’s not possible to use that way outside of the shortcode, but within the shortcode an if-else-routine should be possible somehow.

1 Like

Thanks @davidsneighbour!

Yes - I prefer keeping the two as I find it easier to read.

My version adds some error checking (since I know I’ll mistype at some point), which makes it messy of course:

layouts/shortcodes/if_eq.html

{{ $vars_set := true }}
{{ $name := .Get 0 }}

{{ if or (not (isset .Params 0)) (eq $name "") }}
  {{ $vars_set = false }}
  {{ errorf "if_eq: Environment variable name cannot be empty" }}
{{ end }}

{{ $value := .Get 1 }}

{{ if or (not (isset .Params 1)) (eq $value "") }}
  {{ $vars_set = false }}
  {{ errorf "if_eq: String to check cannot be empty" }}
{{ end }}

{{ if eq $vars_set true }}
  {{ $result := getenv $name }}

  {{ if eq $result "" }}
    {{ errorf "if_eq: Environment variable not set: %s" $name }}
  {{ end }}

  {{ if eq $result $value }}
    {{ .Inner }}
  {{ end }}
{{ end }}

(Any pointers on how to improve this are greatly appreciated!)

I’d be careful about adding shortcodes that mirror the behavior of templates. If you abuse that, then at some point you’ll end up defining your own “template language”, and writing content will end up being similar to writing a template, when the design of Hugo suggests that you should keep those two matters separate.

A more user-friendly version could be defining the shortcode so as to call it like this:

{{% audience "demo" %}}
# Welcome to the demo!
... (some content for demo)
{{% /audience %}}

I think that this looks better to if_eq, but it’s a matter of preference. Good luck!

Edit: now that I read the thread more carefully, this is more or less what @zwbetz suggested

1 Like

Thanks @acanalis. That’s a great point.

(I’m a software developer, so thinking in a “formal programming language” is natural :slight_smile:)

1 Like