Hugo: do not escape HTML in a page .Title when generating <title> tag in the header.html partial

2.9k views Asked by At

In my Hugo-based website, I often use <span> tags within my post titles. I am experiencing an issue where this HTML is always escaped in one particular context. As an example, take a post where the title given in the header of the Markdown file is as follows:

title: 'This is a title with Spanish: <span lang="es">Hola!</span>'

In the single.html partial of my Hugo theme, <h2 class="posttitle">{{ .Title | markdownify }}</h2> works correctly, it passes This is a title with Spanish: <span lang="es">Hola!</span> to the final HTML of the page.

However, in the header.html partial of my Hugo theme, <title>{{ .Title | markdownify }}</title> does not work. Instead, Hugo passes an escaped string to the final HTML of the page: <title>This is title with Spanish: &lt;span lang=&#34;es&#34;&gt;Hola!&lt;/span&gt;</title>

How can I achieve the same behavior in header.html as in single.html?

EDIT: My theme is exceedingly simple, the hugo-xmin theme with minimal changes. My theme’s header.html partial is as follows:

<!DOCTYPE html>
<html lang="{{ .Site.LanguageCode }}">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{{ .Title | markdownify }} &#124; {{ .Site.Title }}</title>
    <link rel="stylesheet" media="screen" href="{{ "/css/style.css" | relURL }}" />
    <link rel="stylesheet" media="screen" href="{{ "/css/screen.css" | relURL }}" />
    {{ partial "head_custom.html" . }}
  </head>
  <body>
    <h1 id="sitetitle">.Site.Title</h1>
    <p id="sitedescription">{{ $.Site.Params.description }}</p>
    <nav>
    <ul class="menu">
      {{ range .Site.Menus.main }}
      <li><a href="{{ .URL | relURL }}">{{ .Name }}</a></li>
      {{ end }}
    </ul>
    <hr/>
    </nav>

and my theme’s single.html file is as follows:

{{ partial "header.html" . }}
<main>
<div class="article-meta">
<h2 class="posttitle">{{ .Title | markdownify }}</h2>
Published on <a href="{{ .RelPermalink }}"><time>{{ .Date.Format "2006-01-02" }}</time></a>
</div>
{{ .Content }}
</main>

{{ partial "footer.html" . }}
2

There are 2 answers

8
justinw On

If you want to avoid escaping, you should use the safeHTML function.

{{ .Title | safeHTML }}

This is not a working solution. Even with this function placed into the header.html partial, the HTML continues to be escaped.

This could be an issue with an older version of Hugo, I am on v0.74.3 and it seems to be working as intended. You might want to upgrade if you're not on the latest version or check on the discourse if you are unable to upgrade.

1
n m On

I downloaded your nonworking-blog minimal example and was able to fix your issue by doing two things:

  1. Put the following at the bottom of the config.toml:
[outputFormats]
  [outputFormats.html]
    isPlainText = true
  1. Comment out line 34 in layouts/_default/list.html so it now looks like this:
{{/*
{{ template "_internal/pagination.html" . }}
*/}}

I did #2 because it was producing an error that I don't have time to look into now, but the key to solving your issue is outputFormats, which are discussed at https://gohugo.io/templates/output-formats/, especially this:

isPlainText
use Go’s plain text templates parser for the templates. Default: false.

If anyone knows how to fix the line-34 problem, I'd love to understand that.

BTW, I've been using isPlainText = true for more than a year on my Infinite Ink site and so far have not had any problems (but I do not use any {{ template … }} calls).