Render Hooks not ... hooking

Hi, I’m processing some text stored in front matter (for a forestry site) using :

{{ $text | $.Page.RenderString }}

which is producing ok HTML but is not pulling the render hook.

Has anyone else had problems?

I’m not entirely sure if this is a recent problem or not or if it is chalked up to some structural issue of my project. I can share the repo with @bep if needed.

You cannot access the Markdown Render Hook from a template, these only work with Markdown syntax for links or images entered in content files.

From both the documentation and experience (and a test that I did on another site – where the render hooks are, for some reason working), this is not the case.

Just like with markdownify, you can apply .RenderString via the .Page (so… .Page.RenderString) to an arbitrary piece of markdown.

Ok, found out about some interesting things:

@bep @alexandros you might be interested in this behavior – let me know if you would like me to make a support ticket.

Seems like a few things : 1) something funky is happening when {{ .Content }} is/isn’t generated 2)caching causing it hard to debug

So I have a template:

<!DOCTYPE html>
<html lang="{{ .Site.Language }}">
  <body>
      {{ "*hello* this is some markdown. ![this is (not) an image](https://gohugo.io/commands/)" | .Page.RenderString }}
      <br>
      {{ ( string .Params.mark ) | .Page.RenderString }}  <= pulling some markdown from frontmatter
  </body>
</html>

which produces :

<!DOCTYPE html>
<html lang="en">
  <body>
      <em>hello</em> this is some markdown. <img src="https://gohugo.io/commands/" alt="this is (not) an image">
      <br>
      <em>hello</em> this is some markdown. <a href="https://gohugo.io/commands/">this is a link</a>
</body>
</html>

ok, no render hooks … looks like it it rendering the markdown “normally”

Now, with this as the template :

<!DOCTYPE html>
<html lang="{{ .Site.Language }}">
  <body>
      {{ "*hello* this is some markdown. ![this is (not) an image](https://gohugo.io/commands/)" | .Page.RenderString }}
      <br>
      {{ ( string .Params.mark ) | .Page.RenderString }}  <= pulling some markdown from frontmatter
      <br>
      {{.Content}}
  </body>
</html>

it generates what is expected (though i think b/c of some caching it only refreshes correctly on the second save) :

<!DOCTYPE html>
<html lang="en">
  <body>
      <em>hello</em> this is some markdown. 
<figure>
  <img src="https://gohugo.io/commands/"
       alt="this is (not) an image"
       style="">

    <figcaption>title</figcaption>

</figure>
      <br>
      <em>hello</em> this is some markdown. <a href="https://gohugo.io/commands/" target="_blank">this is a link</a>
      <br>
</body>
</html>

Strange, no?

NB
I’ve tried this on my larger project which is a Forestry site so everything is within the Front matter. Basically how I handle things is that I parse through the front matter tree and call different partials which render/insert the html. I’ve found that I only have to call {{ $c := $.Page.Content }} at the “lowest level” partial which calls {{ $markdown | $.Page.RenderString }} (where $markdown is some markdown in the frontmatter) to have the render hooks hook.

hey, just wanted to check in to see if others have dealt with this, too.

Yeah, I’m having issue with this too.

I swear I had it working a couple weeks ago. I don’t know if an update to the latest version of Hugo broke this again.

But same issue for me. I have a Frontmatter key that holds a string of markdown content. When I run that through {{ .text | $.Page.RenderString }} the Render Hook is no longer changing the images to the formant that I want. The render hook isn’t firing,

Again, switching form “markdownify” to $.Page.RenderString seemed to work at first, but that did have the caching issue. But now it doesnt work at all.

Also, when it was working, once I edited any part of the md file, the RenderHook wouldn’t fire when the refresh was sent to the browser. I’d have to Save any other file to get the RenderHook to get applied.

I’m sure we are pushing the envelop here, but this is an awesome use of Forestry. I seems like RendHooks work great when used with the “.Content” but we are running into issues when trying to apply RenderHooks to Markdown strings contained in the frontmatter.

OK! Here is a weird fix. If I put a call .Content at the top, I can get the RenderHooks to work for all the Frontmatter Markdown strings below.

Here’s and example:

<div>{{ .Content }}</div>
<div>{{ .text | $.Page.RenderString }}</div>

This will make the RenderHook work for both outputs.

However, in this arrangement, the RenderHook wont be applied to .text, but it will for .Content

<div>{{ .text | $.Page.RenderString }}</div>
<div>{{ .Content }}</div>

And as we know, just piping .text through $.Page.RenderString without .Content being called prior, wont cause the RenderHooks to fire.

<div>{{ .text | $.Page.RenderString }}</div>

I’m sure it makes since to the Hugo dev team. I’m sure that this function was conceived for use with .Contnet because that’s were the content is! However, when making a site for a client, we want to make the layout on the page modular. We want them to be able to move the parts around. Forestry allows us to do this with what they call “Blocks.” This allows us to have multiple content sections on the page. For example, consider this layout: Navigation, Featured Image, Into Paragraph, Image Gallery, and then a Final paragraph in the footer. In this scenario, there are 2 text based content areas, not just one main one.

This is why figuring this out is important. It let’s us leverage the power for Hugo and Forestry to make awesome websites without WordPress.

So, currently, in my html templates, I include a call to .Content(even though the content area is empty) in order to get the RenderHooks to fire. It’s a hack. But it works. I’m not sure if this is a race condition or an order of operations issue. I’m might be apply this incorrectly too. Regardless Hugo still fucking rocks!

Please advise.

I suggest that you share a sample project that reproduces the issue for people to look at.

Sure. Here is a quick example site I threw together to show the issue.

https://brownerd.gitlab.io/renderhookissue/

Source code here:

I tested the sample repo and I can confirm this behavior.
It appears that if the .Content variable is not present in a template .RenderString does not work
Not sure if this qualifies as a bug or if it works as intended. I cannot answer that.

However I tried out a few things.
I suggest that instead of calling the empty .Content variable like you do in the template simply store it in a variable:

  {{ $c := .Content }}
  <div>{{ .RenderString .Params.text }}</div>

The above appears to trigger the .RenderString function and the markup within the parameter is outputted by the Markdown Render Hook, as expected, but it is slightly cleaner than what you have right now, since the stored variable is not called for use in the template.

Ok. Good suggestion. I implemented that in my current project and it works as well. I renamed the variable to $noop.