Preventing escaping in Shortcodes

Hey everybody,

I have a weird escaping issue I’m not sure how to solve. On a site I’m building I have a shortcode (“review”) to add a review to the page. The review shortcode intends to add both the “structured data in JSON-LD format” and the visible HTML of the review.

My content page (which is generated from the review database periodically includes this:

{{% review name="Reviewer" %}} Love's this product {{% /quote %}}

This is layouts/shortcodes/review.html:

<script type="application/ld+json">
{
  "@context": "http://schema.org/",
  "@type": "Review",
  "itemReviewed": {
    "@type": "Product",
    "name": "XYZ",
    "url": "{{ "services" | absLangURL }}"
  },
  "author": "{{ .Get "name" }}",
  "reviewBody": "{{ .Inner }}"
}
</script>

<div>
  <p>{{.Inner}} - {{ .Get "name" }}</p>
</div>

The result is:

<script type="application/ld+json">
{
  "@context": "http://schema.org/",
  "@type": "Review",
  "itemReviewed": {
    "@type": "Product",
    "name": "XYZ",
    "url": "http:\/\/localhost:1313\/en\/services"
  },
  "author": "Reviewer",
  "reviewBody": " Love\x27s this product"
}
</script>

<div>
  <p>Love's this product - Reviewer</p>
</div>

Two things get escaped in the JSON-LD part (but not the HTML part). The url and the reviewBody. So it seems to be caused by Hugo assuming it needs to handle the JSON-LD part differently. Especially the escape in the reviewBody is ‘illegal’ in JSON.

I’ve tried using &apos; in the review text, but then it just gets escapes to \x26apos; which is again illegal. I tried adding | safeHTML and | safeJS but both don’t seem to affect the outcome.

For the url I’ve tried (with no effect):

"url": "{{ "services" | absLangURL | safeURL }}"

Please help me understand what I can do to prevent this escaping behaviour within a Hugo Shortcode!

Try removing the double quotes that wrap your url value

1 Like

Thanks! That solves the first issue with the ‘url’ indeed.

I feel the parser is trying the be ‘too smart’ here and there should be a way to work in ‘pure raw’ mode as well… But I can live with this…

Do you also have a fix for the html entity escaping one (as that is the real blocker)?

Ok… Your suggestion got me thinking about solving the second (blocker) issue as well. Just removing the double quotes results in an unquoted string (whereas the URL string got automagically quoted)…

But by using:

 "reviewBody": "{{ printf "\"%s\"" .Inner | safeJS }}"

The parser sees unquoted code, and does not escape the JSON values, and I can add the double quotes within the printf.

Thanks for the hint into the right direction (although it feels like a dirty fix for something that shouldn’t be escaped in the first place)

Glad to hear that you got the remaining items fixed :+1:

I know what you mean in terms of there must be a better way. This is why I prefer building my JSON in Hugo template code, then rendering it with jsonify. See an example here: https://github.com/zwbetz-gh/uswds-hugo-theme/blob/master/layouts/index.json.json

1 Like

Yeah… I’ve thought about that.

The thing is… It feels like the reviews (multiple ones) should actually be in a data template. But as far as I can figure out, shortcodes cannot access the $.Site.Data, so you cannot range over it in a shortcode. So to access the data template you would need to use a partial / layout… But the data is part of a regular page, so using a different page type and layout page seems overcomplicating it as well…

Shortcodes can access the data dir. Try it like this:

site.Data

There was another issue there apparently.

If there are files that cannot be parsed correctly in the data/ directory, hugo silently stops parsing / including data files!

I had a html file in my data/ directory for other reasons (included in some partial). My review data was not populated as a result!.. I now moved the html file out, and I can indeed access the data template from my shortcode…

Is this an issue that needs reporting on github?

I don’t think so. Since HTML isn’t a supported data file format.

So shouldn’t hugo produce an error then when it encounters an unsupported file format? The (unmentioned) side effect is now that hugo ignores all the actual correct data files and is silent about it. So site.Data is totally empty, even though you might have 10 correct data templates in there.

If the effect of an unsupported file format in data/ is so extreme, shouldn’t hugo just panic?

Hmm. I’ll let one of the developers speak to this.