Allow .html instead of .md for pages and sections

A week and a half ago we deployed our new website at, and it’s using Zola. (The /help pages are not currently in Zola, but will be at some point not too distant.)

I personally only set the Zola project up at the start and did a few bits of content here and there towards the end like the signup page, but I observed a regular annoyance: Markdown only works well for pages that are predominantly prose with no special formatting; on pages that need to be almost entirely exclusively fancy formatting, Markdown is really annoying, because it loves to mangle the arbitrary HTML that you’re writing. Most specifically, you must eschew either the conventional indentation of your HTML, or blank lines; because if you use both, then your indented HTML following a blank line will be treated as a code block instead. (Our old site also suffered from this nuisance, as content was all fed through, which handles this situation a little differently—and I just now found our DPA page ruined by this incompatibility between and CommonMark, which I’ll deploy a fix for on Monday.)

It seems to me that, at the user level, there is a simple and obvious solution for this pain: allow pages and sections to use the extension .html instead of .md, and disable Markdown mangling processing in that case.

A couple of alternatives available to users are: making a template for each such page, and having the pages be empty stubs; or having the HTML sit beside the page Markdown file and use load_data. Either way, you now have two files to care about, possibly in different places, and it’s just not neat. They’re both clearly workarounds rather than solutions. (I am also assuming in_search_index = false on these pages, because that’s our case; think through the implications of not this yourself.)

I have not looked at the implementation ramifications of such a change. I imagine that there should be no substantial problem; for pages, there are already multiple candidates, and foo/, and this is essentially just adding two more; sections I cannot speak for.

A variant that would probably be easier to implement, but which I don’t much like, would be allowing markdown = false in the frontmatter to disable Markdown interpretation, yielding a .md file that is actually HTML rather than Markdown.


I ran into the same issues with sites I’ve made in SSG before.

My preference is one of the options you mentioned, having a template per page. I’m not comfortable with loading .html as pages/sections as it would essentially be 2 completely different models (no front-matter for .html), causing issues when iterating sections/pages. It would also mean that templates would be in 2 different directories that would be need to be watched.

Why? The front-matter is not part of Markdown, it’s a Zola thing.

I’m not suggesting that these HTML files be templates: just that by changing from .md to .html, Markdown processing will not occur.

I see, but people would still expect to be able to use Tera constructs in it right? It doesn’t look like a worthwhile improvement to me over setting template and having all the templates in one place

These are not templates. This is a matter of content that happens to need enough manually-written markup.

Perhaps the clearest way for me to express why this should be content and not templates is searching. (Ideally search operates upon source text with markup stripped, whether it be Markdown or HTML.) If you shift such pages as choose to use HTML into templates, you can no longer search them.

I confess that sometimes I would like to be able to write a page as a template, but that’s definitely a different feature request from this.

I totally agree but people are definitely going to ask for things like extending blocks. I’m not sure what’s the best way there, are shortcodes not good enough?
If I had to pick, I would have a raw = true in the front-matter equivalent to your markdown = false just to be sure people don’t misinterpret that as being a template, the file being still a .md.

I just came up with another approach for this: wrap everything in a noop shortcode, because that stuff doesn’t get treated as Markdown.


{{ body | safe }}

Then, at the start of the page body, add {% raw() %}, and at the end, {% end %}.

I don’t like this solution, partly because it confuses syntax highlighters that think they’re still dealing with Markdown because it’s a .md file, and partly because it’ll be confusing to other authors too. But it’s what I’m going with on my own website now, where I have concluded that I really don’t mind writing in HTML, and doing so saves my a surprising amount of trouble, mostly caused by indentation following blank lines. (My own currently-deployed website uses Hyde, where pages are full Jinja2 templates; there, I wrote everything in HTML with a few conveniences courtesy of Jinja2 extensions, and didn’t use Markdown at all.)