Wanted feature: renderhooks more similar to shortcodes (.Parent)

Features I would like:

  • The variable .Parent be disponible from renderhooks, and overall hooks be treated with more homogeneity as are shortcodes and vice versa.
  • [Imagining] section be automatically offset when same section present in frontmatters

In general, make it so ALL parameters that can be changed in config but apply to pages individually, can be changed in frontmatters

A render hook is for overriding the default markdown rendering.
So the content it uses it plain markdown on a page.
render-link and render-image templates already know from what page they were called from.
Can you give an example of where you need to be using a render-hook that is not on page content?

I think you mean [imaging]
If you want per page control over imaging settings you can do that already with frontmatter and templating / shortcodes / renderhooks.
Let’s say you have a page where you want to set a low quality for a lot of page images. If it overrides the default, does it generate a low quality logo, a low quality opengraph sharing image?
You can’t do some of the most useful quality changes with an override, for example a retina image can usually be served more compressed. You need two quality settings and so you have to template in that fine grain control.
In short, if you want to do fancy stuff with images, just template it.

1 Like

What would the .Parent point to?

Ok, oh crap, Imaging. Sorry, French here. It’s automatic… I’m convinced, somewhat, still annoyed by the apparent lack of consistency, even though here it appears justified. But on the other hand, what would it cost to be able to override defaults on a per-page basis, if users like it that way ? Is this a security issue ? Let them override whatever they want, and template/shortcode the hell out of that if they want too.

.Parent would point to the last shortcode context the image (or whatever expression, say, a codeblock) has been through. Whatever included in the stack inside a .Inner would qualify. There’s a point to be made if other customized contexts (whatever inside layouts/ that is not the default) could figure in the Ancestor list, I think yes, but it doesn’t matter if the rules are consistent.


Image 7 and H occupies half of 70% of the viewports. ImageR 0 and T takes 70%/3 = 23.3% (occupies the same raw). Different contexts but same case for optimization. Image V N L S K share 35% / 5 so 7%. Image 7 takes the whole 70%. And everything gets double below a viewport of 6cm. I could come up with more complicated, but this already would require knowing how many children the .center class (which {{<center>}} applies to its content) has.

You’ll probably think this is useless and could be done otherwise or doesn’t need to be attempted.

I’m all for getting your content displayed exactly as you want it.

Could you use {{< center 5 >}} and {{< center 3>}} to add a grid (maybe flex fall back) with that many elements and use the number to help you resize them also?

I don’t know if there is a way using the image ordinals and shortcode ordinals to work out automatically how many images are present for each center shortcode.

As far as I saw the image .Ordinal counts how many times the hook’s been called either inside the page or each shortcode calls. So it’s reset within each shortcode call… but its “.Ordinal”, not “.TotalNumberOfImages” so we can’t use that.
The content is displayed correctly already, but not processed as efficiently as it could, if it knew the specific proportion the image has regards to the page.

Not sure how ideal this is, just a suggestion. I’d be interested in other ways to get there.

{{% sidebyside n=4 %}}
{{% /sidebyside %}}

Shortcode can handle the surrounding div to get a 4 column css grid
And then in your render-image hook read the n=4 and use it to resize to a quarter size.

{{ $url := urls.Parse .Destination }}
{{ $n := $url.Query.n }}
{{- $src := (.Page.Resources.GetMatch $url.Path) -}}

You might need to calculate the required size taking into account a border, I did something like this to make a neat grid, with perfectly resized images:
{{- $sqsize := math.Round (div (sub $containersize (mul (sub (int $n) 1) $bordersize)) (int $n)) }}

You’ll have some difficulties with different aspect ratio images I expect.

Great, inverse polish notation :sweat_smile:
I didn’t think of using shortcode parameters… The issue with this, is that actually I rarely ever use {{<center>}}, but just {.center} instead !
Also, how would I read n=4 from the hook, since .Parent doesn’t work from there ?

The hook will process each image (of the shortcode block) separately so you need to send the ?n=4 query for each of the four images.
Nothing stopping you using .center for single images?

Not exactly sure what you mean by this. You don’t need to pass anything from shortcode to hook, just feed each one the info they need.
The shortcode is there to surround the .Inner with a div, then the .Inner is processed and we make the render hook reads the query and resize appropriately.

<div style="display: grid;  grid-template-columns: repeat({{ $cols }}, 1fr);">
{{ .Inner }}

I should have used something other than using “n” for the shortcode, as they can be separate, I called it $cols here.


Oh sorry, I didn’t see that, because I never stray away from proper markdown. It’s intelligent but I can’t use this.

I do, but the main use is to apply it to the surrounding paragraph:


This will change the paragraph’s display to flex and all .image under that paragraph shares the width. Very useful and practical, no cheating, no shortcode. But I doubt the number of children can be passed down as a variable in any way to their render-image hooks calls

Do you have a problem with a paragraph around figure elements with this?

Anyway I think you can do what you want.
The markdown of the images stays default, you just surround them with a shortcode as you showed above:

{{% centersomeimages numberofimages=4 %}}
{{% /centersomeimages %}}

The {{% %}} would process .Inner with the render-image hook, but let’s not dump the .Inner as it is.
We need to process the .Inner line by line and add something we can pass to the render-image hook. I choose to add an attribute (which I think needs to be on a newline).
Then, because it is the {{% %}} each $imagestring is now a “markdown image with attribute” and is sent to the render-image hook

{{- $numberofimages := .Get "numberofimages"}}
{{ $Inner := chomp .Inner }}
{{ $imagelist := split $Inner "\n" }}
{{ range after 1 $imagelist }}
{{ $imagestring := print . "\n" "{." $numberofimages "}" }}
{{ $imagestring }}
{{ end }}

(apologies for any hackiness above, it can be rewritten less clumsily I am sure, took me too long as it was)

The render-image hook then has access to the numberofimages value from the shortcode, which was the problem we we trying to solve.

{{- $src := ($.Page.Resources.GetMatch .Destination) -}}
{{ (int .Attributes.class) }}

You can then use that integer value with some maths for the .Resize and job done!

Damn, might impressive.
Looks hacky but actually it’s smart and doesn’t maim markdown so I can’t complain, and it’s straightforward enough that even I (which hate GoTemplate) understands almost immediately.
{.center} is fine, but being pure css, there’s no way to for the hook to know how many children it has, hence the relative size of each image and process it accordingly…
Well I’ll probably not be using this now (I stopped using the shortcode version of <center>) but I’ll be able to if I ever want to style a group of pictures (or rather, of anything that has a renderhook) using a collective property.

It would be neat if we gathered all tricks of that kind into one ordered community-driven repository. The forum isn’t the easiest to search in.

The point of this was so it does know how many images there are in the shortcode, you either

  1. pass the number of images when you add the shortcode to your markdown, as shown
  2. (better but didn’t get around to it) use len() in the shortcode to count the number of images/lines and it can then be automatically.

So whichever way you choose you can use this number to resize the images more appropriately.