Let’s make a website with Quarto

David Schoch

GESIS

2023-06-20

Websites with Quarto

  • Websites are essentially format: html + a Quarto Project

  • Websites and books are actually very similar (in the Quarto sense) since they assemble multiple pages into one resource

Why not WordPress, Tumblr, Medium.com, Blogger.com, etc?

  • No R Markdown support (even math support is often nonexistent or awkward)

  • Huge benefits of static websites compared to dynamic websites

    • all static files, no PHP or databases, no login/password, work everywhere (even offline)

    • typically fast to visit (no computation needed on the server side), and easy to speed up via CDN

Create a website project

Create a website:

quarto create-project MySiteName --type website

Create a blog:

quarto create-project MyBlogName --type website:blog

Create a book:

quarto create-project mybook --type book

In RStudio: New Project > [Quarto Website/Quarto Blog/Quarto Book]
Also support in VS Code

Creating a website

$ quarto create-project MyWebsite --type website
Creating project at /home/david/Documents/tmp/MyWebsite:
  - Created _quarto.yml
  - Created index.qmd
  - Created about.qmd
  - Created styles.css

The project file _quarto.yml

this is where you customize the overall appearance and preferences

project:
  type: website

website:
  title: "MyWebsite"
  navbar:
    left:
      - href: index.qmd
        text: Home
      - about.qmd

format:
  html:
    theme: cosmo
    css: styles.css
    toc: true

In built Themes

Themes

https://quarto.org/docs/output-formats/html-themes.html

default, cerulean, cosmo, cyborg, darkly, flatly, journal, litera, lumen, lux, materia, minty, morph, pulse, quartz, sandstone, simplex, sketchy, slate, solar, spacelab, superhero, united, vapor, yeti, zephyr

or create your own

format:
  html:
    theme: custom.scss
    css: styles.css
    toc: true

very similar to customizing presentations!

Possibilities are endless

customize, customize, customize

_quarto.yml

project:
  type: website

website:
  site-url: "https://mr.schochastics.net"
  title: "schochastics"
  favicon: "static/favicon.png"
  twitter-card:
    creator: "@schochastics"
    site: "@schochastics"
    description: "I’m the team lead for Transparent Social Analytics in the Department for Computational Social Science at GESIS and I develop tools in R."
    image: "static/img/avatar.png"
    card-style: "summary"
  search: false
  open-graph: 
    site-name: schochastics
    description: "I’m the team lead for Transparent Social Analytics in the Department for Computational Social Science at GESIS and I develop tools in R."
    image: "static/img/avatar.png"
  navbar:
    logo: "static/logo.png"
    title: false
    background: primary
    right:
      - href: publications/index.qmd
        text: Publications
      - href: http://blog.schochastics.net
        text: Blog
      - href: project/index.qmd
        text: Projects
      - href: material/index.qmd
        text: Material
      - href: about/index.qmd
        text: About me
  page-footer:
    left: "© 2022 David Schoch"
    center: "powered by [quarto](https://quarto.org)"
    right:
      - icon: twitter
        href: https://twitter.com/schochastics
      - icon: github
        href: https://github.com/schochastics
      - text: <i class="ai ai-google-scholar" role="img"></i>
        href: https://scholar.google.de/citations?user=MFlgHdcAAAAJ&hl=en
      - text: <i class="ai ai-orcid" role="img"></i>
        href: https://orcid.org/0000-0003-2952-4812
      - text: <i class="bi bi-mastodon"></i>
        href: https://fosstodon.org/@schochastics

format:
  html:
    theme: 
      - cosmo
      - custom.scss
    css: 
      - styles.css
      - academicons.css
    toc: true
execute: 
  freeze: auto

customize, customize, customize

custom.scss

/*-- scss:defaults --*/
$body-bg: #333333 !default;
$body-color: #9EEBCF;
$link-color: white;
$font-family-sans-serif: 'IBM Plex Sans';
$font-family-monospace: 'IBM Plex Sans';

$navbar-bg: #333333;
$navbar-fg: #9EEBCF;
$navbar-hl: #9EEBCF;

/*-- scss:rules --*/
@font-face {
    font-family: 'Nova Square';
    src: url('static/fonts/novasquare-regular-webfont.woff2') format('woff2'),
         url('static/fonts/novasquare-regular-webfont.woff') format('woff');
    font-weight: normal;
    font-style: normal;

}

@font-face {
    font-family: 'IBM Plex Sans';
    src: url('static/fonts/IBMPlexSans-Regular.woff2') format('woff2'),
        url('static/fonts/IBMPlexSans-Regular.woff') format('woff');
    font-weight: normal;
    font-style: normal;
}

@media screen and (min-width: 56em) {
  html {
    font-size: 1.1em;
  }
}

customize, customize, customize

styles.css

/* css styles */
div.sourceCode{
  background-color: black;
}


h1,h2,h3,h4{
  font-family: 'Nova Square';
}

.listing-title{
  color: white;
  text-decoration: underline;
  font-weight: 700;
}

pre{
  border: 1px solid white;
  color: var(--navbar-fg);
  padding: 5px 5px 5px 5px;
}

code{
  color: var(--navbar-fg);
}

/* inline code */
.post-body>p>code{
  background-color: rgba(255,255,255,.1);
}

a.btn-links:hover{
  background-color: rgba(255,255,255,.1)!important;
}

.habout{
  font-size: 3rem;
  font-family: 'Nova Square';
  font-weight: 700;
}

h1,h2,h4{
  font-weight: 700;
}

h4.f4{
  font-size: 1.75rem;
}

h1.f3{
  font-weight: 700;
}

/* navbar kink */
@media screen and (min-width: 999px) {
  .navbar .navbar-nav .nav-link {
    color: #9EEBCF;
    font-size: 1rem;
    text-transform: uppercase;
  }
  .navbar .navbar-nav .nav-link:hover {
    color: #9EEBCF;
  }
  .navbar .navbar-nav .nav-item {
    position: relative;
  }
  .navbar .navbar-nav .nav-item::after {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    background-color: #ffd700;
    width: 0%;
    content: "";
    height: 1px;
    transition: all 0.5s;
  }
  
.navbar .navbar-nav .nav-item:hover::after {
    width: 100%;
  }
}

.navbar-brand>img {
    max-height: 48px;
    width: auto;
    padding-right: 6px;
}

.nav-footer a{
  color: #9EEBCF;
}

.active {
  border-bottom: 1px solid #ffd700;
}

.navbar-brand {
    position: relative;
    width: 170px;
    left: 15px;
    background-size: contain;
}

/*footer*/
.nav-footer{
  border-top: 0px !important;
}

/*buttons*/

.btn-outline-success{
  border-color: #9EEBCF;
  background-color: transparent;
}

.btn-outline-success:hover{
  border-color: white;
  background-color: #666666;
}

.btn-outline-success a{
  text-decoration: none;
  text-transform: uppercase;
}

/* grid cards */
.card-body{
  background-color: #333333;
}

.card-img-top{
  background-color: #333333;
  width: 80%;
  margin-left: auto;
  margin-right: auto;
}

.borderless{
  background-color: #333333;
}

.quarto-grid-item img.thumbnail-image {
    object-fit: contain;
}

.thumbnail-image:hover{
  opacity:75%;
}

.center{
   text-align: center;
}

div.column.col-v-center{
   vertical-align: middle;
}

.home-title{
  font-size: 2em;
}

.socials{
  padding-top: 0.5em;
  padding-bottom: 1em;
}

.socials a{
  color: #9EEBCF;
  margin-left: 0.5em;
}

Adding an About page

---
twitter-card:
    image: images/profile-preview.png
    creator: "@schochastics"
open-graph: true
title: "David Schoch"
image: images/profile-preview.png
about:
    template: trestles
    links:
    - icon: twitter
        text: Twitter
        href: https://twitter.com/schochastics
    - icon: github
        text: Github
        href: https://github.com/schochastics
---

About page templates

about:
  template: trestles

Publishing

(not limited to websites)

There are many ways to publish Quarto websites. Since rendered content uses standard formats (HTML, PDFs, etc.) it can be published anywhere. Additionally, there is a quarto publish command available for easy publishing to popular services (GitHub, Netlify, Posit Connect, etc.)


as well as various tools to make it easy to publish from a Continuous Integration (CI) system.

Interlude: CI

Continuous integration is a DevOps software development practice where developers regularly merge their code changes into a central repository, after which automated builds and tests are run.

In simpler terms:
Instead of rendering your website and uploading the new version, CI allows to simply “push” code to a repository and the website is automatically updated

Publishing with GitHub

GitHub Pages enables you to publish websites based on a GitHub repository.

There are three publishing options from Quarto:

  • Render sites on your local machine to the docs directory, check the rendered site into GitHub, and then configure your GitHub repo to publish from the docs directory.

  • Use the quarto publish command to publish content rendered on your local machine.

  • Use a GitHub Action to automatically render your files (a single Quarto document or a Quarto project) and publish the resulting content whenever you push a source code change to your repository.

Using CI with GA

(assuming your website source code is checked into GitHub)

  1. freeze computations (add to _quarto.yml)
execute:
  freeze: auto
  1. (re)render
$ quarto render
  1. publish locally
$ quarto publish gh-pages
  1. add .github/workflows/publish.yml with this content

  2. commit and push






you only need to do this once

(going forward, only step 5 is needed)

Build your own website