D.8 The default HTML template

As we mentioned in Section 1.5, the default output format for an Rmd document in blogdown is blogdown::html_page. This format passes a minimal HTML template to Pandoc by default:

<!-- BLOGDOWN-HEAD -->
$for(header-includes)$
$header-includes$
$endfor$
$if(highlighting-css)$
<style type="text/css">
$highlighting-css$
</style>
$endif$
$for(css)$
  <link rel="stylesheet" href="$css$" type="text/css" />
$endfor$
<!-- /BLOGDOWN-HEAD -->

$for(include-before)$
$include-before$
$endfor$
$if(toc)$
<div id="$idprefix$TOC">
$toc$
</div>
$endif$

$body$

$for(include-after)$
$include-after$
$endfor$

You can find this template file via blogdown:::pkg_file('resources', 'template-minimal.html') in R, and this file path is the default value of the template argument of html_page(). You may change this default template, but you should understand what this template is supposed to do first.

If you are familiar with Pandoc templates, you should realize that this is not a complete HTML template, e.g., it does not have the tags <html>, <head>, or <body>. That is because we do not need or want Pandoc to return a full HTML document to us. The main thing we want Pandoc to do is to convert our Markdown document to HTML, and give us the body of the HTML document, which is in the template variable $body$. Once we have the body, we can further pass it to Hugo, and Hugo will use its own template to embed the body and generate the full HTML document. Let’s explain this by a minimal example. Suppose we have an R Markdown document foo.Rmd:

---
title: "Hello World"
author: "Yihui Xie"
---

I found a package named **blogdown**.

It is first converted to an HTML file foo.html through html_page(), and note that YAML metadata are ignored for now:

<!-- BLOGDOWN-HEAD -->
<!-- /BLOGDOWN-HEAD -->

I found a package named <strong>blogdown</strong>.

Then blogdown will read the YAML metadata of the Rmd source file, and insert the metadata into the HTML file so it becomes:

---
title: "Hello World"
author: "Yihui Xie"
---

I found a package named <strong>blogdown</strong>.

This is the file to be picked up by Hugo and eventually converted to an HTML page of a website. Since the Markdown body has been processed to HTML by Pandoc, Hugo will basically use the HTML. That is how we bypass Hugo’s Markdown engine BlackFriday.

Besides $body$, you may have noticed other Pandoc template variables like $header-includes$, $css$, $include-before$, $toc$, and $include-after$. These variables make it possible to customize the html_page format. For example, if you want to generate a table of contents, and apply an additional CSS stylesheet to a certain page, you may set toc to true and pass the stylesheet path to the css argument of html_page(), e.g.,

---
title: "Hello World"
author: "Yihui Xie"
output:
  blogdown::html_page:
    toc: true
    css: "/css/my-style.css"
---

There is also a pair of HTML comments in the template: <!-- BLOGDOWN-HEAD --> and <!-- /BLOGDOWN-HEAD -->. This is mainly for method = 'html_encoded' in blogdown::build_site() (see Section D.9). This pair of comments are used to mark the HTML code fragment that should be moved to the <head> tag of the final HTML page. Typically this code fragment contains links to CSS and JavaScript files, e.g., those requested by the user via the css argument of html_page(), or automatically generated when HTML widgets are used in an Rmd document. For method = 'html', this code fragment is not moved, which is why the final HTML page may not conform to W3C standards. If you want to customize the template, you are recommended to use this pair of comments to mark the HTML code fragment that belongs to the <head> tag.