Questions about Render Hooks

First of all, Happy Holidays to everyone. :christmas_tree:

I have questions on the latest Render Hooks capability of Hugo. Render Hooks documentation

This may be obvious to most of the people, but I need some clarification as to what implication this will has on the content authoring.

Render Hooks seems to provide functionality for replacing some of the built-in shortcodes, especially the ones related to hyperlink and image processing. My questions are:

  1. Can we replace ref and relref shortcodes with the use of Render Hooks?
  2. Can we replace figure shortcode with the use of Render Hooks?
    • If so, how can we pass all the parameters to the Render Hooks template?
    • If not, is the Render Hooks only applicable to the images as page resources (page bundles)?

Thanks in advance.

In most cases the answer to your questions are yes. But you cannot pass custotom parameters to these hooks, so if you need that, then no (it has been discussed in another thread; it may be possible to encode this into the URL, maybe).

That said, for all of my uses of ref/relref/image in Markdown, render hooks should work great.


How can we access the render hooks variables from the outside?

For example I tried to access the .Text variable from a head partial through various contexts (.Page, .Content) but every time I encountered an error in the form of .Text cannot be evaluated in hugolib.Page or html.template

I can get what I need by using findRE in .Content but I was kind of hoping that there was a more straightforward way.

By the way Happy Christmas and all the best!

As there would be potentially many links in page, something like .Content.Text would not make sense.

There is no predefined data structure you can access outside of the hook template. So you need to make up your own if you need it and store it with Scratch.

In my use case I want to grab the .Text value of the first image in a content file and populate the meta description of the page.

However since Render Hooks are not available from the outside I am doing the following (without Scratch):

{{ with .Content }}{{ $txt:= findRE `figcaption\>(.*?)\<` . 1 }}{{ printf "%s" $txt | replaceRE `\[figcaption\>` `` | replaceRE `\<\]` `` }}{{ else }}{{ .Site.Params.description }}{{ end }}

The above gets me where I want.

Small Note:
A difference between Blackfriday and Goldmark is that with the latter Hugo’s functions work after the Markdown has been processed to HTML whereas with Blackfriday the opposite happened.

It is very important to me to minimize the front matter that needs to be entered manually in the Hugo projects that I maintain and I am willing to sacrifice build time to generate the necessary data automatically.

So that is why I need to do the above.

Also content portability is very important and I use Hugo shortcodes only if I do not have another choice.

Again thanks for the Render Hooks. I have already updated a big project and everything works as intended with the bonus of pure Markdown content files.

I would think that using scratch for this would be both faster and cleaner, e.g. in your hook template:

{{ if not .Page.Scratch.Get "caption }}
{{ .Page.Scratch.Set "caption" .Text }}
{{ end }}

You would need to access .Content before you access that scratch variable.

Thank you for the suggestion. I tried entering it in the render-image.html template however even before trying to access the scratch variable Hugo complains about:
at <.Page.Scratch.Set>: wrong number of args for Set: want 2 got 3

I don’t quite understand the error message since there are only 2 arguments and not 3.

It’s hard to tell what you did wrong without you showing what you did.

I figured it out.

In the Render Hook template: render-image.html I entered:

{{ .Page.Scratch.Set "alt" .PlainText }}

And then in the meta description partial I get the Scratch Variable like so:

{{ with .Content }}{{ $.Page.Scratch.Get "alt" }}{{ else }}{{ $.Site.Params.description }}{{ end }}

I have a couple of notes:

  • I removed your suggested condition from above i.e. {{ if not (.Page.Scratch.Get "alt") }}...{{ end }} because the Scratch Variable was populated in the first page (in alphabetical order) in which .PlainText was encountered but then it was left blank in subsequent pages.

  • Setting a Scratch Variable stops at the last instance of .PlainText encountered in a page. So for pages with many images the last value is stored.

I do not remember what exactly I did wrong last night -it was after a Christmas party- but anyway I figured it out this morning.

Again thank you for your help. :four_leaf_clover: