Templating javascript variables

I have some code that I need to use in a shortcode.

<div id="waveform">
    <script type="text/javascript">
        var x = WaveSurfer.create({
            container: document.querySelector('#waveform'),
            barWidth: 1,
            barHeight: 1, // the height of the wave
            barGap: null
        });

        x.load("/audio/{{ index .Params 0 }}");
    </script>
    <button class="btn btn-primary" data-action="play" onclick="x.playPause()">Play | Pause</button>
</div>

The only issue is that var x cannot be used in every instance of the shortcode and I need this variable to be dynamically named. I have tried using an md5 hash of the .Inner content and assigning it to a variable such as $id, however, this creates more problems than it solves as something like var $id = assigns the md5 hash as a string.

Has anyone got a solution for creating js vars using layout/shortcode/templating in Hugo?

Try data attributes:

I’m using this in one of my components where I have hugo params set javascript variables.

1 Like

Okay, for the benefit of everyone else here is my solution.

You simply call your shortcode like this

{{ $id | safeJS }}

Which makes the string turn into a variable without quotes. Works well!

My only problem now is md5 hashes dont work all the time as variables. I think the best way is to create variables using .Scratch.Page and then increment this value each time the shortcode is parsed.

I do this as follows:

{{ if not (.Page.Scratch.Get "waveform") }}
{{ .Page.Scratch.Set "waveform" 1}}
{{ else }}
{{ .Page.Scratch.Add "waveform" 1 }}
{{ end }}

I wonder can anyone here direct me on something really stupid? Can I do a string concatenation inside {{}} in order to use the “waveform” .Scratch to create a new templated variable which would look something like {{ $id := "wavesurfer" + .Page.Scratch.Get "waveform"}}.

Ideally in the code I would end up with something like wavesurfer_1 if I called {{$id}} on the first instance of the shortcode.

Did you try the .Ordinal Shortcode variable that @bep recommended in your other post?

Hi @zivbk1, I think our posts have overlapped a little but I have achieved something similar using .Page.Scratch.Add and checking if the .Scratch already exists.

1 Like

Okay, I have a good solution that works for creating javascript variables including a little string concatenation of Hugo variables using printf

{{ if not (.Page.Scratch.Get "wavesurfer") }}
<script src="https://unpkg.com/wavesurfer.js"></script>
{{ .Page.Scratch.Set "wavesurfer" true }}
{{ end }}

{{ if not (.Page.Scratch.Get "waveform") }}
{{ .Page.Scratch.Set "waveform" 1}}
{{ else }}
{{ .Page.Scratch.Add "waveform" 1 }}
{{ end }}
{{ $num := .Page.Scratch.Get "waveform"}}
{{ $id := (printf "wavesurfer_%d" $num)}}

<div id="waveform_{{ .Page.Scratch.Get "waveform"}}">
    <script type="text/javascript">
        var {{$id | safeJS}} = WaveSurfer.create({
            container: document.querySelector('#waveform_{{ .Page.Scratch.Get "waveform" }}'),
            barWidth: 1,
            barHeight: 1, // the height of the wave
            barGap: null
        });

        {{$id | safeJS}}.load("/audio/{{ index .Params 0 }}");
    </script>
    <button class="btn btn-primary" data-action="play" onclick="{{$id | safeJS}}.playPause()">Play | Pause</button>
</div>

Thanks for the help everyone! It has been really valuable. I hope someone else searching for how to do this will find my posts :slight_smile:

1 Like