Deprecate markdownify?

Since it was merged, perhaps this topic should be revisited?

The global page function is really useful in certain situations, but you need to have a clear understanding of context, caching, and concurrency before using it:

https://gohugo.io/functions/global/page/#warnings

I could be wrong about this, but I think changing what’s happening underneath from:

.Site.Home.RenderString

to

page.RenderString

has the same potential for misuse under certain conditions.

For most markdown conversion it’s irrelevant, but you still need to have a clear understanding of context, caching, and concurrency to avoid things like:

https://github.com/gohugoio/hugo/issues/9692

My advice is to always use .Page.RenderString instead of markdownify:

The context issue in .RenderString bit me some time back before I found .Page.RenderString. I support aliasing markdownify to the latter.

The markdownify function is already aliased to .Site.Home.RenderString. For the most part it works fine, but it can cause some subtle problems that are easy to miss and difficult to troubleshoot:

https://github.com/gohugoio/hugo/issues/9692

RenderString is a method on a Page object. It is not a function; it needs a page reference. Currently that page reference is the home page, which is the underlying cause of the subtle problems referenced in #9692.

OK, so why not use a reference to the current page be aliasing markdownify to page.RenderString? Because the global page function has its own subtleties:

https://gohugo.io/functions/global/page/#warnings

I stand by my original suggestion: deprecate the markdownify function.

1 Like

In that case, you have my support.

I actually find markdownify more appropriate. It naturally makes me think that I can write Markdown syntax directly within a string. On the other hand, RenderString already suggests that it’s a string, so why would I need to render it again? What’s the purpose of that?

This isn’t an issue of naming. It’s an issue of function.

In that case: html-ify +1

That assumes that every renderer going forward will produce HTML. We support 6 content formats today including HTML, so we have 5 renderers. “RenderString” is generic; we don’t know the input, and we don’t know the output.

https://gohugo.io/methods/page/renderstring/

So this is essentially an ambitious function—a superhero of sorts—that we expect to handle everything. But sometimes, that makes it harder for me to decide whether I should use it or not. If I had a clearer understanding of what each function is meant for, it would reduce my cognitive load. It’s similar to the global objects like page and site—sometimes I struggle with whether to use the global scope or the local one, and which approach feels more “Hugo-like.”

That’s what this topic about. Deprecate the one that has problems, and give you one choice—the right choice.

I’ve studied Hugo’s source code, and I see that RenderString is a completely independent function—it handles everything from preparing the context to finding the template and rendering. That made me wonder: why provide such a function? What are the intended use cases?

If site is responsible for the site and page is responsible for individual pages, then all page rendering should be handled by page. Even for rendering shortcodes, page could simply pass the relevant context to the shortcode.

I completely agree with having just one choice—one that feels Hugo-like.

What are the intended use cases?

Rendering markup as inline or block, accepting any of the 6 supported content formats.

If you are trolling me, you’re doing a great job.

I apologize if it seemed like I was trolling you—that was not my intention at all.

What I meant was, my understanding is that Markdown inside .Content can be directly rendered, and Markdown in the front matter can be rendered with markdownify. Markdown inside shortcodes can also be directly rendered, and there are even hooks available for customization.

What I’m asking is, aside from these scenarios, is there any other situation that I might be missing where content can only be rendered via RenderString?

You cannot use markdownify to:

  • Render a single line of Markdown to a paragraph
  • Render Org, AsciiDoc, Pandoc, or reStructuredText

Additionally, the current implementation of markdownify (aliased to site.Home.RenderString) has several subtle problems:

https://github.com/gohugoio/hugo/issues/9692

A global page reference would sort-of help, but I suspect also cause problems. See the warnings.

I’ve spent enough time on this. Trust me, use .RenderString instead of markdownify.

I trust your advice and will proceed with using RenderString for now.


My two cent: RenderString provides a lot of functionality, which can be somewhat bloated. Enhancing markdownify, or creating specialized rendering functions (such as orgnify) to handle Org, AsciiDoc, Pandoc, and reStructuredText formats, would be a more flexible and streamlined solution.

  1. Enhancing markdownify to handle single-line Markdown as paragraphs
    By extending markdownify to recognize and handle single-line Markdown content, and render it as a paragraph, this functionality could better meet practical needs. For example, the content could be wrapped in a <p> tag if it’s a single line.
  2. Creating something like orgnify
    For Org, AsciiDoc, Pandoc, and reStructuredText formats, creating separate rendering functions (such as orgnify) to handle these specific formats would make the code more modular and avoid over-reliance on RenderString.

This is just a thought I had, and I wanted to share it with you. Apologies if this feels like going on and on. Please don’t feel the need to reply to this—just wanted to share my thoughts.

No, it can’t.

<h1>{{ .Title | markdownify }}</h1>
1 Like

I see your point, but I feel that this example might not be the best illustration of the issue.

If I understand correctly, the problem here is not really about markdownify itself but rather a misuse of it. There are different perspectives on this, but one is from the viewpoint of a theme creator. If I were writing a theme and used the following code:

<h1>{{ .Title | markdownify }}</h1>

Expecting it to allow inline formatting like:

<h1>Title <b>Bold</b></h1>

That wouldn’t work because <h1> tags don’t support inline Markdown formatting like that. If someone truly needs such behavior, they might need a different approach, such as handling it via <custom_title> or using a custom function.

This doesn’t seem like something markdownify should solve, nor do I think it needs to. The learning curve for this is quite low—once users realize the limitation, they will naturally look for alternative solutions.

What do you think?

That is false.

I think it’s time to archive this thread.