Hugo

Lodash template tags are escaped since Hugo 0.19

Hello there. I had used lodash template tags for my widget. It worked well until I updated Hugo from 0.18.1 to 0.19.

% hugo version
Hugo Static Site Generator v0.19 darwin/amd64 BuildDate: 2017-02-27T19:21:29+09:00

In 0.19, some tags are escaped after the build. The template with the problem is below:

<script type="text/template" id="js-qiita-posts-tmpl">
<% list.forEach(function (item) { %>
  <li class="qiita-tl__item">
    <a class="qiita-tl__link" href="<%= item.url %>" target="_blank">
      <span class="qiita-tl__stock" target="_blank">
        <%= item.stock_count %> <span class="qiita-tl__stock-unit">STOCKS</span>
      </span>

      <h3 class="qiita-tl__title"><%= item.title %></h3>

      <p class="qiita-tl__tags">
        <% item.tags.forEach(function (tag) { %>
        <span class="qiita-tl__tag"><%= tag.name %></span>
        <% }); %>
      </p>
    </a>
  </li>
<% }); %>
</script>

The output from 0.19 is this:

<script type="text/template" id="js-qiita-posts-tmpl">
&lt;% list.forEach(function (item) { %>
  <li class="qiita-tl__item">
    <a class="qiita-tl__link" href="<%= item.url %>" target="_blank">
      <span class="qiita-tl__stock" target="_blank">
        &lt;%= item.stock_count %> <span class="qiita-tl__stock-unit">STOCKS</span>
      </span>

      <h3 class="qiita-tl__title">&lt;%= item.title %></h3>

      <p class="qiita-tl__tags">
        &lt;% item.tags.forEach(function (tag) { %>
        <span class="qiita-tl__tag">&lt;%= tag.name %></span>
        &lt;% }); %>
      </p>
    </a>
  </li>
&lt;% }); %>
</script>

The lodash tags outside double quotes are escaped unexpectedly. I also tried these functions but the result isn’t desirable. :disappointed_relieved:

template:

{{ printf "<%= contribution %>" }}
{{ htmlUnescape "<%= contribution %>" }}
{{ htmlUnescape "&lt;%= contribution %&gt;" }}

output:

&lt;%!=(MISSING) contribution %!&gt;(MISSING)
&lt;%= contribution %&gt;
&lt;%= contribution %&gt;

Currently, I haven’t tried 0.20, because it hasn’t appeared to Homebrew, yet.

My questions :

  1. Is it a bug? or new expected behavior from 0.19?
  2. Are there any solutions to keep lodash tags unescaped?

It is probably changed behaviour in the Go version in use, you may search for it here:

This escaping of HTML templates in Go’s HTML templates are mostly security motivated – which may not be an issue when you control the input yourself. In Hugo >= 0.20 you can switch to using Go’s text template package per output format by defining isPlainText=true.

See https://gohugo.io/extras/output-formats/

Very thanks! I found the issue about the problem at there:

html/template: <script> tags with type “text/template” now escapes EJS templates · Issue #18569 · golang/go

It seems this behavior will be fixed in future version of Go. For the current use, I will try the new option when I could install Hugo 0.20.

1 Like

I got hugo 0.21 and what I wanted to do was successful :grinning:

% hugo version
Hugo Static Site Generator v0.21-DEV darwin/amd64 BuildDate: 2017-05-03T17:47:35+09:00

I added them below into the config.toml:

[mediaTypes."text/template"]
suffix = "ejs"

[outputFormats.EJS]
mediaType = "text/template"
isHTML = true
isPlainText = true

Then I included the partial like this:

  {{ (partial "my-ejs-partial.ejs" .) | safeHTML }}

The safeHTML filter is necessary to keep it unescaped.

1 Like

This is an amazing fix, thanks so much @hokkey!

One minor change – as of Hugo 0.44, the suffix field needs to be changed to suffixes as an array. For example:

[mediaTypes."text/template"]
  suffixes = ["ejs"]

[outputFormats.EJS]
  mediaType = "text/template"
  isHTML = true
  isPlainText = true

The rest all works as per above. Thanks again for the great save!