Bug? Hugo doesn't use _markup/render-link.html when piped into markdownify

Not sure if this is a bug, by design, or and operator error, so I’ll ask here first.

I am making use of render-link.html to decorate external links. It works fine in a .md file, however I also expected it to work when piping content from a data file into a html template with markdownify.

render-link decorates my external links…


{{- $link := .Destination }}
{{- $isRemote := strings.HasPrefix $link "http" }}
{{- if not $isRemote -}}
{{- $url := urls.Parse .Destination }}
{{- $fragment := "" }}
{{- with $url.Fragment }}{{ $fragment = printf "#%s" . }}{{ end -}}
{{- with .Page.GetPage $url.Path }}{{ $link = printf "%s%s" .RelPermalink $fragment }}{{ end }}{{ end -}}
<a href="{{ $link | safeURL }}"
   {{- with .Title}} title="{{ . }}"{{ end }}
   {{- if $isRemote }} target="_blank" rel="noopener" aria-label="This is an external link (opens in a new tab)"{{ end }}>
   {{- .Text | safeHTML -}}
   {{- if $isRemote }} <i class="fas fa-external-link-alt"></i>{{ end -}}

excerpt from themes/[mytheme]/layouts/partials/team.html:

{{ with .description }}<p class="team_text">{{ . | markdownify }}</p>{{ end }}

excerpt from data/team.yml:

   description: >
        Blah Blah Blah [example thing](https://example.com)

The link is markdownified, but not decorated using render-link.html as I would expect.
It seems like the new features were not fully implemented?

I can reproduce this as well. It would appear that the contents passed into markdownify are not utilizing Goldmark, which is the only markdown processor which enables render hooks.

Note that this is only supported with the Goldmark renderer.

You need to use .RenderString (instead of markdownify).
.RenderString being a Page’s method, it provides the Page context, critical to Render Hooks.

Now if your template is not bound to any page (Data file). You should be able to have it work using a random page, say the homepage: site.Home.RenderString $string.
But it seems your “render hook” template uses .Page.GetPage which invokes a call relative to the “current page” so this might be problematic.


Thanks. Unfortunately using .RenderString really fails the intuitive test, since the behavior is so different, but I sympathize why page context is needed.

I wonder for a future version of Hugo, how difficult it would be to have the code that wraps markdownify provide the page context so this “just works” even with .Page.GetPage in a partial template?


I’m curious as what you mean by “intuitive test”?

I’m not sure how your code which relies on your links being relative to a given page (.Page.GetPage) could work without a page…

Now if your .GetPage could work as relative to the project instead, you could use site.GetPage and forgo of the need a particular page as context, you could use any page as context, the homepage as in my example or any…

My 2 cents - I want to write github-compatible (or commonmark?) markdown where possible, and want to be able to navigate anchored pages in VS Code, github and hugo, i.e.

[some link to other page anchor](other-page.md#anchor-link-on-that-page)

This new functionality allows me to do that (unless it was there before and I’ve missed something).

However I’ve spent a day or two getting my render-link.html working because of | markdownify vs. | .Page.RenderString.

I agree with the comment above, it’s not ‘intuitive’:

markdownify: “Runs the provided string through the Markdown processor.”
.RenderString: “Renders markup to HTML.” (NEW in 0.62)

I had a shortcode that essentially wrap the .Inner in a div, e.g.:

{ .Inner | markdownify }

as soon as I switched to using render-link.html none of the links in the .Inner were using the render-link.html - presumably for the reason mentioned above, i.e. this works with render-link.html:

{ .Inner | .Page.RenderString }

and I’ve had to replace that it many shortcodes.

Anyway, thanks for adding this as it is helpful.