-
Notifications
You must be signed in to change notification settings - Fork 817
/
website-blog.qmd
414 lines (298 loc) · 16.7 KB
/
website-blog.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
---
title: 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.
::: {.panel-tabset group="tools-tabset"}
### VS Code
To create a new blog project within VS Code, execute the **Quarto: Create Project** command from the command-palette:
![](images/vscode-create-project-command.png)
Then, select **Blog Project**:
![](images/vscode-create-project-blog.png){.border}
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:
![](images/vscode-create-project-directory.png){.border}
The new blog project will be created and opened within VS Code. Click the **Preview** button (![](/docs/tools/images/vscode-preview-icon.svg){fig-alt="Preview icon"}) to preview the blog:
![](images/vscode-create-project-render-blog.png)
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.
### RStudio
To create a new blog project within RStudio, use the **New Project** command and select **Quarto Blog**:
::: {layout-ncol="2"}
![](images/rstudio-project-new-directory.png){.border}
![](images/rstudio-project-blog.png){.border}
:::
Then, provide a directory name and other relevant options for the blog:
![](images/rstudio-project-blog-options.png){.border}
Click the **Render** button to preview the blog:
![](images/rstudio-project-blog-preview.png)
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.
### Terminal
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:
``` {.bash filename="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:
``` {.bash filename="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](website-listings.qmd) for all of the documents in the `posts` directory:
![](images/myblog.png){.border fig-alt="Screenshot of a blog page. There is a navigation bar at the top with the blog title ('myblog') on the left, and on the right: 'About', a GitHub icon, a Twitter icon, and a Search icon. The body has two posts listed with titles, tags, description and preview ordered by date. On the right of the body are categories with counts of posts next to them."}
Here's the source code for the home page:
``` yaml
---
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.
::: callout-warning
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](website-listings.qmd) 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:
``` yaml
---
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:
``` yaml
---
title: "Post With Code"
description: "Post description"
author: "Fizz McPhee"
date: "5/22/2021"
categories:
- news
- code
- analysis
---
```
See the article on [Categories](website-listings.qmd#categories) to learn more.
## About Page
The `about.qmd` document includes additional information on the blog and its author. For example:
![](images/about-jolla.png){.border fig-alt="Screenshot of an about page. It has a large round circle in the top center with an image shown. Below that is a name in large type, with smaller placeholder body text beneath it. There are two buttons at the bottom, one for twitter, and one for GitHub."}
Here's what the source code of an `about.qmd` might look like:
``` markdown
---
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](/docs/websites/website-about.qmd) 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 to indicate a post is a draft. For example:
``` yaml
---
title: "My Post"
description: "Post description"
author: "Fizz McPhee"
date: "5/22/2021"
draft: true
---
```
Draft posts will appear when you preview the site, but will be blank when you render the site and will not appear in listings, navigation, the site map, or site search. You can read more about drafts in [Website Drafts](website-drafts.qmd).
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:
``` yaml
---
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 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](/docs/projects/quarto-projects.qmd#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:
``` yaml
# options apply to all posts in this folder
# freeze computational output
freeze: true
```
See the article on the [`freeze`](/docs/projects/code-execution.qmd#freeze) option to learn more about freezing computational output within websites.
## Themes
Blogs can use any of the 25 [Bootswatch](https://bootswatch.com/) themes included with Quarto. You can also [create your own](/docs/output-formats/html-themes.qmd#theme-options) themes. The default blog generated by `quarto create project` uses the [cosmo](https://bootswatch.com/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:
::: {layout="[40,60]"}
::: theme-list
- [default](https://bootswatch.com/default/)
- [cerulean](https://bootswatch.com/cerulean/)
- [cosmo](https://bootswatch.com/cosmo/)
- [cyborg](https://bootswatch.com/cyborg/)
- [darkly](https://bootswatch.com/darkly/)
- [flatly](https://bootswatch.com/flatly/)
- [journal](https://bootswatch.com/journal/)
- [litera](https://bootswatch.com/litera/)
- [lumen](https://bootswatch.com/lumen/)
- [lux](https://bootswatch.com/lux/)
- [materia](https://bootswatch.com/materia/)
- [minty](https://bootswatch.com/minty/)
- [morph](https://bootswatch.com/morph/)
- [pulse](https://bootswatch.com/pulse/)
- [quartz](https://bootswatch.com/quartz/)
- [sandstone](https://bootswatch.com/sandstone/)
- [simplex](https://bootswatch.com/simplex/)
- [sketchy](https://bootswatch.com/sketchy/)
- [slate](https://bootswatch.com/slate/)
- [solar](https://bootswatch.com/solar/)
- [spacelab](https://bootswatch.com/spacelab/)
- [superhero](https://bootswatch.com/superhero/)
- [united](https://bootswatch.com/united/)
- [vapor](https://bootswatch.com/vapor/)
- [yeti](https://bootswatch.com/yeti/)
- [zephyr](https://bootswatch.com/zephyr/)
:::
::: theme-thumbnails
**litera**
[![](images/theme-litera.png){style="border: solid silver 1px;" fig-alt="Screenshot of blog with litera theme."}](https://bootswatch.com/litera/)
**solar**
[![](images/theme-solar.png){style="border: solid silver 1px;" fig-alt="Screenshot of blog with solar theme."}](https://bootswatch.com/solar/)
**morph**
[![](images/theme-morph.png){style="border: solid silver 1px;" fig-alt="Screenshot of blog with morph theme."}](https://bootswatch.com/morph/)
:::
:::
## 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:
1. In the `_quarto.yml` file, add a `site-url` and `description` to the `website` key (without these options being set in the project file, Quarto cannot generate a feed). For example:
``` yaml
website:
title: "myblog"
site-url: https://www.myblogexample.io
description: "A great sample blog"
```
2. In your blog home page `index.qmd` add the `feed: true` option to the listing. For example:
``` yaml
---
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](/docs/websites/website-listings.qmd#feeds).
::: callout-tip
## Including an RSS Link on the Navbar
You can add an RSS link to your navbar by including the following in your `_quarto.yml` project file. For example:
``` yaml
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:
``` yaml
---
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](/docs/publishing/index.qmd) describes in more detail how to publish to the following services:
- [Quarto Pub](/docs/publishing/quarto-pub.qmd)
- [GitHub Pages](/docs/publishing/github-pages.qmd)
- [Netlify](/docs/publishing/netlify.qmd)
- [Posit Connect](/docs/publishing/rstudio-connect.qmd)
- [Firebase](/docs/publishing/other.qmd#google-firebase)
- [Site44](/docs/publishing/other.qmd#site44)
- [Amazon S3](/docs/publishing/other.qmd#amazon-s3)
## 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:
1. 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.
``` html
<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-->
```
::: callout-warning
The 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.
:::
2. Create the file `subscribe.html` in the root of your project.
3. Paste the HTML for your subscription widget into `subscribe.html` and save the file.
4. Add `subscribe.html` to the `margin-header` in your `_quarto.yml` file:
``` yaml
website:
# (additional metadata excluded for brevity)
margin-header: subscribe.html
```
The result looks like this:
![](images/myblog-subscribe.png){.border fig-alt="Screenshot of blog with a Subscribe section in the top of the right-hand section of the bofy. There is an input field marked 'email address' and a button below it labelled 'Subscribe'."}