# Access shortcode parameter in JavaScript and refer to current "a"-link inside shortcode file

**URL:** <https://discourse.gohugo.io/t/access-shortcode-parameter-in-javascript-and-refer-to-current-a-link-inside-shortcode-file/32301>\
**Category:** support\
**Created:** [April 10, 2021, 8:38pm UTC](https://discourse.gohugo.io/t/access-shortcode-parameter-in-javascript-and-refer-to-current-a-link-inside-shortcode-file/32301 "2021-04-10T20:38:23Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![User2](https://avatars.discourse-cdn.com/v4/letter/u/ecb155/32.png) [@User2](https://discourse.gohugo.io/u/User2)\
**Post date:** [April 10, 2021, 8:38pm UTC](https://discourse.gohugo.io/t/access-shortcode-parameter-in-javascript-and-refer-to-current-a-link-inside-shortcode-file/32301/1 "2021-04-10T20:38:23Z")

</div>

Hello everyone,  
yes, the title is very confusing, I’ll clear that up. There are in fact a few things I’m not too sure about and reading through the entire documentation still left a few questions.  
I don’t want to bring up an XY-question where I ask about Y because I think it helps me to do X, instead of just asking about X right away. I’ll explain what I want to achieve, add my thoughts about what I tried already and I’d be happy if you could suggest a better, shorter and cleaner way to achieve this if there is one and I’m sure there might be one.

So I want to run a certain JavaScript function, when you click a certain link, which is wrapped in a shortcode, but this should only be done if the shortcode declaration contains a third given parameter. For that I’d simply use {{ with .Get 2 }}.  
In this JavaScript code, I want to refer to the link, this link is linking to. Additionally, I want to remove the hash (if an ID is currently mentioned in the URL) and use this to remove something from the localStorage. The JavaScript code itself shouldn’t be a problem.  
I’d theoretically want to use something like this inside an inline style-tag in the shortcode HTML file (quick pseudo-code):

```auto
const hashIndex = "{{ .Get 0 }}".indexOf('#') || url.Length;
const newUrl = "{{ .Get 0 }}".substring(0, hashIndex);

localStorage.removeItem("${newUrl}-something");
```

but that isn’t possible due to the .Get 0 not being valid (while the first parameter is always the URL it’s referring to).  
I thought about saving the URL in a meta-tag, but I’d have to loop through all occurences of this meta-tag anyway and somehow differentiate which belongs to which. I could technically give the “a”-link a special ID, but I’m not sure how, since that all is taking place inside a shortcode HTML file.

I tried a lot of things, combining a lot of different things, but I couldn’t come up with a reasonable solution.  
I mean for the click function, if the “a”-link doesn’t have a unique ID, I could have an ugly workaround doing something like this:

```auto
{{ with .Get 2 }}
<a href="{{ .Get 0 }}" class="link">{{.Inner}}</a>
{{ else }}
<a href="{{ .Get 0 }}" class="link" onClick="someFunction()">{{.Inner}}</a>
{{ end }}
```

but that is pretty ugly and inconvenient for several reasons. Using an onClick over an addEventListener in JS might not be the preferred way anyway and this whole thing looks a little bit hacky. There would still be the problem with the link though, because I can’t include the .Get 0 as a parameter either.

So whatever I tried, I ended up encountering an obstacle somewhere.

---

<div class="post-metadata">

**Author:** ![davidsneighbour](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/davidsneighbour/32/24507_2.png) [@davidsneighbour](https://discourse.gohugo.io/u/davidsneighbour)\
**Post date:** [April 11, 2021, 5:04am UTC](https://discourse.gohugo.io/t/access-shortcode-parameter-in-javascript-and-refer-to-current-a-link-inside-shortcode-file/32301/2 "2021-04-11T05:04:21Z")

</div>

> **[safeHTMLAttr](https://gohugo.io/functions/safehtmlattr/#readout)**
>
> Declares the provided string as a safe HTML attribute.

Check the sample on that page. You need to mark those attributes as safe. How you use them with JavaScript in the end is your thing 🙂

---

<div class="post-metadata">

**Author:** ![User2](https://avatars.discourse-cdn.com/v4/letter/u/ecb155/32.png) [@User2](https://discourse.gohugo.io/u/User2)\
**Post date:** [April 11, 2021, 10:43am UTC](https://discourse.gohugo.io/t/access-shortcode-parameter-in-javascript-and-refer-to-current-a-link-inside-shortcode-file/32301/3 "2021-04-11T10:43:42Z")

</div>

I’m afraid I didn’t quite understand this. I tried something according to the documentation, but unfortunately that still leads to a dead end.

I tried using this HTML in my link.html file (the shortcode I’m using) and I’m afraid it’s horribly wrong:

```auto
{{ with .Get 2 }}
<a href="{{ .Get 0 }}" target="{{ .Get 1 }}" class="shortcode-link" {{ printf "onClick=`deleteScrollPos(%q)`" .Get 0 | safeHTMLAttr }}>{{.Inner}}</a>

<script>
    function deleteScrollPos(url) {
        const hashIndex = url.indexOf('#') || url.Length;
        const newUrl = url.substring(0, hashIndex);
        localStorage.removeItem("${newUrl}-scrollPos");
    }
</script>
{{ else }}
<a href="{{ .Get 0 }}" target="{{ .Get 1 }}" class="shortcode-link">{{.Inner}}</a>
{{ end }}
```

I’m getting this error:

```auto
execute of template failed: template: shortcodes/link.html:18:12: executing "shortcodes/link.html" at <.Get>: can't evaluate field Get in type string
```

Besides, this hacky way really doesn’t satisfy me, but I tried to get it working with the simplest way I could think of.

---

<div class="post-metadata">

**Author:** ![davidsneighbour](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/davidsneighbour/32/24507_2.png) [@davidsneighbour](https://discourse.gohugo.io/u/davidsneighbour)\
**Post date:** [April 11, 2021, 11:17am UTC](https://discourse.gohugo.io/t/access-shortcode-parameter-in-javascript-and-refer-to-current-a-link-inside-shortcode-file/32301/4 "2021-04-11T11:17:41Z")

</div>

That is a mess.

- inside of the `with .Get 2` the dot (`.`) is not the parent context, but the content of the third parameter, so `.Get 0` inside there won’t work. you need to get your parameters outside of the with loop.
- the attribute `onclick` looks ok (if the parameter would be right). you are saying "run `deleteScrollPos(Parameter 0)`" but I would use %s instead of %q.
- in the function itself you do some weird stuff that makes me think you have an url as parameter 0. If that is the case, then you add too much as a parameter because you cut everything away until the hash?
- the function will be defined multiple times if you re-use the shortcode on the same page. It should have it’s own name, maybe with a random string, to avoid confusion.
- you could take the URL in Hugo, parse it and add only the hash content as `data-hash` attribute to the link, then define that function one single time and let it check for the data-attribute and do it’s stuff.

And Hugo’s `safe` functions aren’t hacky. They are the safe way to add attributes that you parsed and checked.

---

<div class="post-metadata">

**Author:** ![davidsneighbour](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/davidsneighbour/32/24507_2.png) [@davidsneighbour](https://discourse.gohugo.io/u/davidsneighbour)\
**Post date:** [April 11, 2021, 11:20am UTC](https://discourse.gohugo.io/t/access-shortcode-parameter-in-javascript-and-refer-to-current-a-link-inside-shortcode-file/32301/5 "2021-04-11T11:20:00Z")

</div>

```auto
{{ $parameter0 := .Get 0 }}
{{ $parameter1 := .Get 1 }}
{{ with $parameter1 }}
<a href="{{ $parameter0 }}">some link this is</a>
{{ end }}

```

---

<div class="post-metadata">

**Author:** ![User2](https://avatars.discourse-cdn.com/v4/letter/u/ecb155/32.png) [@User2](https://discourse.gohugo.io/u/User2)\
**Post date:** [April 11, 2021, 12:03pm UTC](https://discourse.gohugo.io/t/access-shortcode-parameter-in-javascript-and-refer-to-current-a-link-inside-shortcode-file/32301/6 "2021-04-11T12:03:59Z")

</div>

Thank you very much for your answer. I understand your points.  
To clear things up: I don’t want to remove everything but the hash, I want to remove the hash and keep everything else. I also didn’t mean Hugo’s safe functions are hacky, I meant the way of creating one link with and one link without an onClick, depending whether there is a third parameter or not, just doesn’t feel clean. But I’d be happy to get it working first.

I guess I understood all your points and changed my code. There is one little issue however. It adds the onClick attribute like that in the final rendered HTML:

```auto
<a href="something" onClick="`deleteScrollPos(/general/the-page/)`">
```

The problem about that: It adds the `` as well, but I couldn’t get it to work without them, because it doesn’t accept %s as a parameter for the JavaScript function.  
Simply using:

```auto
<a href="{{ $p0 }}" target="{{ $p1 }}" class="shortcode-link" {{ printf "onClick=`deleteScrollPos(%s)`" $p0 | safeHTMLAttr }}>{{$inner}}</a>
```

doesn’t work. JavaScript of course doesn’t want to accept this.

---

<div class="post-metadata">

**Author:** ![davidsneighbour](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/davidsneighbour/32/24507_2.png) [@davidsneighbour](https://discourse.gohugo.io/u/davidsneighbour)\
**Post date:** [April 11, 2021, 12:23pm UTC](https://discourse.gohugo.io/t/access-shortcode-parameter-in-javascript-and-refer-to-current-a-link-inside-shortcode-file/32301/7 "2021-04-11T12:23:18Z")

</div>

> [@User2](#):
>
> Simply using:
> 
> ```auto
> <a href="{{ $p0 }}" target="{{ $p1 }}" class="shortcode-link" {{ printf "onClick=`deleteScrollPos(%s)`" $p0 | safeHTMLAttr }}>{{$inner}}</a>
> 
> ```
> 
> doesn’t work. JavaScript of course doesn’t want to accept this.

The problem is “not enough information” 😉 Your sample line looks like the link has the same href as the thing that you want to give to the onclick function. Why not use an empty onclick function call and check this.href (or something that is valid javascript) inside of the function then?

The very specific call to the printf imho is this (not connected to the idea above, just in case you want to go further down the road you are already on):

```auto
{{ printf "onClick=\"deleteScrollPos('%s')\"" ($p0 | safeHTMLAttr) }}

```

- strings in Go need to be encased in `"`
- `"` that you want to print in your HTML need to be slashed out
- in JS you can use single quotes
- then a nice safe bracket around the parameter, just in case Hugo has a bad day. probably not required.

---

<div class="post-metadata">

**Author:** ![User2](https://avatars.discourse-cdn.com/v4/letter/u/ecb155/32.png) [@User2](https://discourse.gohugo.io/u/User2)\
**Post date:** [April 11, 2021, 12:38pm UTC](https://discourse.gohugo.io/t/access-shortcode-parameter-in-javascript-and-refer-to-current-a-link-inside-shortcode-file/32301/8 "2021-04-11T12:38:55Z")

</div>

Thank you very much for your reply. I see what you mean, but I’m quite confused about all that. It seems like JavaScript doesn’t like the slashing out. The first \ seems to be an “Invalid character.” (that’s what the error says). It simply doesn’t like the slashes. Excuse me, if I’m confused about simple things, but I am quite confused right now so even simpler things I’d know would confuse me in that context.

---

<div class="post-metadata">

**Author:** ![davidsneighbour](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/davidsneighbour/32/24507_2.png) [@davidsneighbour](https://discourse.gohugo.io/u/davidsneighbour)\
**Post date:** [April 11, 2021, 12:51pm UTC](https://discourse.gohugo.io/t/access-shortcode-parameter-in-javascript-and-refer-to-current-a-link-inside-shortcode-file/32301/9 "2021-04-11T12:51:38Z")

</div>

If everything goes right the backslash shouldn’t be there when Javascript looks at it. It’s supposed to tell printf to output a `"`. You are doing something else wrong probably. The backslash is there so that `printf` prints the `"` into the parameter.

Please put a sample repo on Github that produces the problem you are encountering and from there we go.

---

<div class="post-metadata">

**Author:** ![User2](https://avatars.discourse-cdn.com/v4/letter/u/ecb155/32.png) [@User2](https://discourse.gohugo.io/u/User2)\
**Post date:** [April 11, 2021, 12:56pm UTC](https://discourse.gohugo.io/t/access-shortcode-parameter-in-javascript-and-refer-to-current-a-link-inside-shortcode-file/32301/10 "2021-04-11T12:56:20Z")

</div>

I am pretty much using the exact same code you sent above while it does make sense to me, JS doesn’t want to accept it.

```auto
{{ printf "onClick=\"deleteScrollPos('%s')\"" ($p0 | safeHTMLAttr) }}
```

And this would be the entire shortcode except the CSS:

```auto
{{ $p0 := .Get 0 }}
{{ $p1 := .Get 1 }}
{{ $p2 := .Get 2 }}
{{ $inner := .Inner }}

{{ with $p2 }}
<a href="{{ $p0 }}" target="{{ $p1 }}" class="shortcode-link" {{ printf "onClick=\"deleteScrollPos('%s')\"" ($p0 | safeHTMLAttr) }}>{{$inner}}</a>

<script>
    function deleteScrollPos(url) {
        const hashIndex = url.indexOf('#') || url.Length;
        const newUrl = url.substring(0, hashIndex);

        localStorage.removeItem("${newUrl}-scrollPos");

        console.log("${newUrl}");
    }
</script>

{{ else }}
<a href="{{ $p0 }}" target="{{ $p1 }}" class="shortcode-link">{{$inner}}</a
{{ end }}
```

I agree, this topic is a little bit cluttered with messages. I am pretty confused why it doesn’t accept it though. There is one other thing I’m not sure about though.  
Will {{ with $p2 }} evaluate false if there is no third parameter?

---

<div class="post-metadata">

**Author:** ![davidsneighbour](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/davidsneighbour/32/24507_2.png) [@davidsneighbour](https://discourse.gohugo.io/u/davidsneighbour)\
**Post date:** [April 11, 2021, 12:58pm UTC](https://discourse.gohugo.io/t/access-shortcode-parameter-in-javascript-and-refer-to-current-a-link-inside-shortcode-file/32301/11 "2021-04-11T12:58:55Z")

</div>

A sample repo has content and a config that sets up something where we can load it and type `hugo` to see what is happening 😉 Knowing only the layout part is not enough, sorry. I can’t see for instance one single sample call to your shortcode in this topic. You are presenting a blackbox and want a solution… Come one.

---

<div class="post-metadata">

**Author:** ![User2](https://avatars.discourse-cdn.com/v4/letter/u/ecb155/32.png) [@User2](https://discourse.gohugo.io/u/User2)\
**Post date:** [April 11, 2021, 1:32pm UTC](https://discourse.gohugo.io/t/access-shortcode-parameter-in-javascript-and-refer-to-current-a-link-inside-shortcode-file/32301/12 "2021-04-11T13:32:38Z")

</div>

After a quick break, I managed to pretty much immediately come to the idea to use backquotes ` instead of quotation marks " and it worked just fine. Putting parenthesis around $p0 | safeHTMLAttr breaks the entire system by the way, so I decided to do it without them.

This worked out in the end:

```auto
{{ printf `onClick="deleteScrollPos('%s')"` $p0 | safeHTMLAttr }}
```

Thank you very much for leading me to the right path. I appreciate your help.
