Creating a Blog
Overview
Quarto websites include integrated support for blogging. Blogs consist of a collection of posts along with a navigational page that lists them in reverse chronological order. Blogs can include a custom about page, publish an RSS feed, and use a wide variety of themes.
You can create websites that consist entirely of a single blog, websites that have multiple blogs, or you can add a blog to a website that contains other content.
Quick Start
Follow the Quick Start for your tool of choice to get a simple blog up and running. After covering the basics, read on to learn about more advanced blog features.
To create a new blog project within VS Code, execute the Quarto: Create Project command from the command-palette:
Then, select Blog Project:
You’ll be prompted to select a parent directory to create the project within. Then, you’ll be asked to name the directory for your blog project:
The new blog project will be created and opened within VS Code. Click the Render button to preview the blog:
The preview will show to the right of the source file. As you re-render index.qmd
or render other files like about.qmd
, the preview is automatically updated.
To create a new blog project within RStudio, use the New Project command and select Quarto Blog:
Then, provide a directory name and other relevant options for the blog:
Click the Render button to preview the blog:
The preview will show to the right of the source file. As you re-render index.qmd
or render other files like about.qmd
, the preview is automatically updated.
To create a new blog project from the Terminal, use the quarto create project
command with blog
, specifying the directory that will hold the new project as first argument:
Terminal
quarto create project blog myblog
This will create the scaffolding for a simple blog in the myblog
sub-directory. Use the quarto preview
command to render and preview the blog:
Terminal
quarto preview myblog
The blog preview will open in a new web browser. As you edit and save index.qmd
(or other files like about.qmd
) the preview is automatically updated.
Here’s a summary of the key files created within the starter blog project:
File | Description |
---|---|
_quarto.yml |
Quarto project file. |
index.qmd |
Blog home page. |
about.qmd |
Blog about page. |
posts/ |
Directory containing posts |
posts/_metadata.yml |
Shared options for posts |
styles.css |
Custom CSS for website |
In the following sections we’ll take a closer look at the various components of the project.
Home Page
The home page is a listing page for all of the documents in the posts
directory:
Here’s the source code for the home page:
---
title: "myblog"
listing:
contents: posts
sort: "date desc"
type: default
categories: true
---
When you render a new post, the listing page will automatically updated, adding the most recent post to the top of the list.
It is not recommended that you use dynamic dates (for example today
or last-modified
) in your blog posts. This will cause the order of your blog and feed to be changed each time the document is rendered or modified.
See the article on Listing Pages to learn more about customizing listings, including use a grid layout rather than the default shown above.
Categories
The listing page is configured to enable categories, which display in the right margin of the page:
---
title: "myblog"
listing:
# (additional metadata excluded for brevity)
categories: true
---
The categories are read from the front matter of documents included in the listing. For example, here is sample post metadata that includes categories:
---
title: "Post With Code"
description: "Post description"
author: "Fizz McPhee"
date: "5/22/2021"
categories:
- news
- code
- analysis
---
See the article on Categories to learn more.
About Page
The about.qmd
document includes additional information on the blog and its author. For example:
Here’s what the source code of an about.qmd
might look like:
---
title: "About"
image: profile.jpg
about:
template: jolla
links:
- icon: twitter
text: Twitter
href: https://twitter.com
# (additional links excluded for brevity)
---
## About this blog
This is the contents of the about page for my blog.
See the article on About Pages to learn about the various options available for customizing page output.
Posts Directory
The posts that make up the contents of the blog are located in the posts
directory.
Add a new post to your blog by creating a sub-directory within posts
, and adding an index.qmd
file to the directory. That qmd
file is the new blog post and when you render that, the blog home page will automatically update to include the newest post at the top of the listing.
Drafts
Add draft: true
to the document options if you’d like a post to not be included in the listing, site map, or site search. For example:
---
title: "My Post"
description: "Post description"
author: "Fizz McPhee"
date: "5/22/2021"
draft: true
---
To publish the post when it is complete, simply remove draft: true
from the document options and then render it.
Last Updated
To indicate the date of the last modification, but preserve the original publication date, you can add the date-modified
field to the document options. For example:
---
title: "My Post"
description: "Post description"
author: "Fizz McPhee"
date: "5/22/2021"
date-modified: "5/23/2021"
---
Freezing Posts
Blogs posts that contain executable code often have the problem that posts created last year can’t be rendered this year (for example, because the packages used by the post have changed). A similar problem can also arise when a blog has multiple contributors and not everyone has the right software (or the right versions) to render all of the posts. Finally, posts that include computations can often take a while to render, and you don’t want the cumulative time required to render the site to grow too large.
The solution to these problems is to freeze the output of computational blog posts. When a post is rendered with freeze: true
, the markdown output from the the underlying engine (e.g. Jupyter or Knitr) is saved. When the entire site is rendered these computations are not re-run, but rather read from the previously frozen results.
The only time an article with freeze: true
is rendered is when you explicitly re-render it. By specifying this option for blog posts you can ensure that posts rendered now will always re-render well with the rest of the site, even if the software required to originally render them isn’t available.
In the default blog we include a file (_metadata.yml
) that establishes shared metadata for all documents within the posts
directory. In this file, we specify that we want freeze: true
set by default for all posts:
# options apply to all posts in this folder
# freeze computational output
freeze: true
See the article on the freeze
option to learn more about freezing computational output within websites.
Themes
Blogs can use any of the 25 Bootswatch themes included with Quarto. You can also create your own themes. The default blog generated by quarto create project
uses the cosmo theme. Here are links to the available themes along with thumbnails of what the simple default blog looks like under a few of them:
RSS Feed
Blogs typically include an RSS feed that allows their content to be easily syndicated to feed readers and other websites. You can enable RSS for a blog by doing the following:
In the
quarto.yml
file, add asite-url
anddescription
to thewebsite
key (without these options being set in the project file, Quarto cannot generate a feed). For example:website: title: "myblog" site-url: https://www.myblogexample.io description: "A great sample blog"
In your blog home page
index.qmd
add thefeed: true
option to the listing. For example:--- title: "myblog" listing: contents: posts sort: "date desc" type: default categories: true feed: true ---
Now, when your site is rendered, an RSS feed will also be generated. To learn more, see the article on RSS Feeds.
You can add an RSS link to your navbar by including the following in your _quarto.yml
project file. For example:
website:
title: "myblog"
site-url: https://www.myblogexample.io
description: "A great sample blog"
navbar:
right:
- icon: rss
href: index.xml
Category Feeds
You can also generate RSS feeds for specific categories in your blog. For example, to create feeds for the categories news
and posts
in a blog, you could write the following:
---
title: "myblog"
listing:
contents: posts
sort: "date desc"
type: default
categories: true
feed:
categories: [news, posts]
---
This will create an index.xml
file with the RSS feed for the listing, but also create an index-news.xml
and index-posts.xml
file with RSS feeds for the respective categories.
Publishing
There are a wide variety of ways to publish Quarto blogs. Blog content is by default written to the _site
sub-directory. Publishing is simply a matter of copying this directory to a web server or web hosting service.
The article on Publishing Websites describes in more detail how to publish to the following services:
Subscriptions
You may want to allow readers of your blog to subscribe to updates via email. You can use a third party email service to manage and send these emails.
Third party email services will typically take your RSS Feed as input (e.g. https://www.myblogexample.io/index.xml
) and provide HTML for a subscription widget that you can place on your blog. A good place to locate that widget is often right margin of your blog.
Here are the steps required to add a subscription widget:
Use your email service features to generate the HTML for your subscription widget. MailChimp, for example, provides HTML like this for a minimal subscription widget.
<span style="font-weight: 600;">Subscribe</span> <!-- Begin Mailchimp Signup Form --> <link href="http://cdn-images.mailchimp.com/embedcode/slim-10_7_dtp.css" rel="stylesheet" type="text/css"> <style type="text/css"> #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; width:170px;} /* Add your own Mailchimp form style overrides in your site stylesheet or in this style block. We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */ #mc-embedded-subscribe-form{margin-left:-5px;} </style> <div id="mc_embed_signup"> <form action="<site_url>" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate> <div id="mc_embed_signup_scroll"> <input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required> <!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups--> <div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_f718424fc5df77c22533bdaa6_a3c37fb57b" tabindex="-1" value=""></div> <div class="optionalParent"> <div class="clear foot" style="margin-top: 10px;"> <input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button"> <p class="brandingLogo"></p> </div> </div> </div> </form> </div> <!--End mc_embed_signup-->
WarningThe above widget HTML will not work in your blog as the subscription HTML needs to contain value specific to your blog. See your email service provider’s instructions for generating a subscription widget.
Create the file
subscribe.html
in the root of your project.Paste the HTML for your subscription widget into
subscribe.html
and save the file.Add
subscribe.html
to themargin-header
in your_quarto.yml
file:website: # (additional metadata excluded for brevity) margin-header: subscribe.html
The result looks like this: