I have a layout which creates some dynamic javascript variable data using newScratch
.
The problem is each call to the scratch’s Set
method is outputting double quotes (""
).
A simplified example, having:
{{ define "foot" }}
<script>
A
{{ $scratch := newScratch }}
{{ $scratch.Set "greeting" "Hello" }}
B
</script>
{{ end }}
will actually output:
<script>
A
""
B
</script>
which is causing issues in my actual code:
{{ define "foot" }}
<script>
{{- $constructorsData := slice -}}
{{- range $constructor := sort $.Site.Data.constructors "name" -}}
{{- $country := index $.Site.Data.countries $constructor.countryId -}}
{{- $constructorData := newScratch -}}
{{- $constructorData.Set "id" $constructor.id -}}
{{- $constructorData.Set "name" $constructor.name -}}
{{- $constructorData.Set "countryAlpha2Code" $country.alpha2Code -}}
{{- $constructorData.Set "countryAlpha3Code" $country.alpha3Code -}}
{{- $constructorData.Set "countryName" $country.name -}}
{{- $constructorsData = $constructorsData | append ($constructorData.Values) -}}
{{- end -}}
var constructorsData = {{ $constructorsData }};
..
</script>
{{ end }}
as the var constructorsData = [..];
output in the generated page has a lot of ""
prepended to it, making the javascript invalid.
Note I was experimenting a bit and when I just remove the opening <script>
tag, the ""
are not outputted anymore…
Am I doing something wrong here as I don’t understand why the ""
s are outputted…?
1 Like
Note until now I was not having any issue without using a Scratch
.
I currently have (which is working):
{{ define "foot" }}
<script>
{{- $constructorsData := slice -}}
{{- range $constructor := sort $.Site.Data.constructors "name" -}}
{{- $country := index $.Site.Data.countries $constructor.countryId -}}
{{- $constructorData := (dict "id" $constructor.id) -}}
{{- $constructorData = merge $constructorData (dict "name" $constructor.name) -}}
{{- $constructorData = merge $constructorData (dict "countryAlpha2Code" $country.alpha2Code) -}}
{{- $constructorData = merge $constructorData (dict "countryAlpha3Code" $country.alpha3Code) -}}
{{- $constructorData = merge $constructorData (dict "countryName" $country.name) -}}
{{- $constructorsData = $constructorsData | append ($constructorData) -}}
{{- end -}}
var constructorsData = {{ $constructorsData }};
..
</script>
{{ end }}
I only wanted to replace all this dict
merging by using a Scratch
…
pamubay
December 30, 2020, 11:26pm
3
you could write it like this
{{ `<script>` | safeHTML }}
A
{{ $scratch := newScratch }}
{{ $scratch.Set "greeting" "Hello" }}
B
{{ `</script>` | safeHTML }}
So Go Templates parser will not detect the <script>
tag and not doing any escaping inside the tag.
2 Likes
Thanks it works! Now I’m wondering what the Go Templates engine does when detecting the <script>
tag…
For future readers,
another simple solution is just to define the Scratch
outside the <script>
tag.
{{ define "foot" }}
{{- $constructorsData := slice -}}
{{- range $constructor := sort $.Site.Data.constructors "name" -}}
{{- $country := index $.Site.Data.countries $constructor.countryId -}}
{{- $constructorData := newScratch -}}
{{- $constructorData.Set "id" $constructor.id -}}
{{- $constructorData.Set "name" $constructor.name -}}
{{- $constructorData.Set "countryAlpha2Code" $country.alpha2Code -}}
{{- $constructorData.Set "countryAlpha3Code" $country.alpha3Code -}}
{{- $constructorData.Set "countryName" $country.name -}}
{{- $constructorsData = $constructorsData | append ($constructorData.Values) -}}
{{- end -}}
<script>
var constructorsData = {{ $constructorsData }};
..
</script>
{{ end }}
bep
December 31, 2020, 11:02am
6
Set returns an empty string, not double quotes, so the quotes comes from “somewhere else”.
You can try
{{- $scratch.Set “greeting” “Hello” -}}
To trim the newlines.
I would discourage following the accepted solution of trying to completely bypassing the template engine’s security model. The correct solution is to use safeJS
.
<script>
{{ $scratch.Set "greeting" "Hello" | safeJS }}
</script>
I don’t recall why we do this, but Set
returns an empty string. Bare strings are considered unsafe in a <script>
context, so the template engine quotes and escapes the string for Javascript.
system
Closed
January 2, 2021, 3:15pm
8
This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.