Since June 25, 2023, I start to move my website from hugo/rmarkdown/blogdown/wowchemy to quarto website. It is difficult to explain why I spend so much time on that. Perhaps because some reasons same as other bloggers: 1. Quarto is the next generation of rmarkdown. 2. Quarto is independent with R or Rstudio. 3. Quarto has a clean file tree for website building. 4. Quarto has cleaner command than hugo (i.e., quarto publish netlify for publishing website etc.).
This blog serves as a note how I customize quarto website bit by bit. It will not be a comprehensive tutorial (much online resources exists) but contain be some tricks.
1 Useful links
Quarto official documentation is always the best place to starts with.
Nicola Rennie’s blog is very inspiring. Nice font setting and background. I feel like Hugo Apéro is the best hugo theme in the market.
Yihui’s blog. As the creator of blogdown, Yihui talked about why not transfer to Quarto :P I am a old player of hugo/blogdown, but I am not good at customizing the website from the scratch. Thus, quarto suits my needs very well. For those who is very experienced at JS, hugo is still a better choice.
Frank Harrel’s blog: R workflow.
Silvia Canelón’s blog: Hello Quarto: Porting my Website from Hugo Apéro
2 Tricks of Quarto
2.1 Code highlighting
The very first trick is using format > html > code-fold: true settings in YAML metadata in _quarto.yml (global) or .qmd (local) to hide the code block as |> Code, like:
Note that the code block can be numbered and added with a left border using code-block-bg: true and code-block-border-left: "#31BAE9"
Code block now also can be shown with language #| echo: fenced. As the code chunk shown below, {r} is explicitly presented. I don’t hate #| as the new way of chuck option setup but when I test the code chuck, I found there is a space between #| and option keys. For example, it should be #| echo: fenced rather than #|echo:fenced. Otherwise, quarto will ignore chunk options.
```{python}#| eval: false#| code-fold: showimport numpy as npiris = np.array(iris)```
2.2 Visual model
Visual model is one of the most appealing feature for Quarto but I am far from a expert in that. It looks like a visual model version of markdown editor (so called WYSIWYM editing, What you see is What you mean) but slightly different. The shortcut of switching between source and visual model is Cmd + Shift + F4 (Thanks to Yihui’s JS for pretty keyboard styling).
::: callout-note {#keyborad} ## Keyboard Shortcut
You can use Shortcodes keyboard shortcuts to display keyboard keys. For example, insert {{< kbd K >}} into Quarto documents displays KK. {{< kbd Shift-Ctrl-P >}} display Shift-Ctrl-PShift-Ctrl-P after rendering. :::
I list some most frequently used keyboard for visual mode editing:
2 By default, it will insert R code chunk. If another language is frequently, use Tools > Modify keyboard shortcuts > filter 'Insert'. There should be a place for setting shortcut for other language.
3 Click `F4` in any place in the div works.
Please also refer to the official document for more shortcuts and features. One thing I found very interesting is single quote mark ` . First, I’m not sure how to escape this in visual model. Second, if you close quote before typing content, like ``, visual mode will escape both quote marks. However, if you type in left quote mark then content and then close quote (i.e., type in`something first, and type closing quote mark), it can quote content correctly.
Last but not least, perhaps just type / in rstudio is a better choice as it will pop up a list of elements to choose.
There is no direct way to display a collapsing button in quarto. I found a way to do that by using bootstrap collapse component. The following code is a simple example of a collapsing button. The button is linked to a collapse component with the id collapseExample. When the button is clicked, the collapse component is shown or hidden.
For more details of bootstrap collapse component, please refer to the official documentation.
Link with href
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis sagittis posuere ligula sit amet lacinia. Duis dignissim pellentesque magna, rhoncus congue sapien finibus mollis. Ut eu sem laoreet, vehicula ipsum in, convallis erat. Vestibulum magna sem, blandit pulvinar augue sit amet, auctor malesuada sapien. Nullam faucibus leo eget eros hendrerit, non laoreet ipsum lacinia. Curabitur cursus diam elit, non tempus ante volutpat a. Quisque hendrerit blandit purus non fringilla. Integer sit amet elit viverra ante dapibus semper. Vestibulum viverra rutrum enim, at luctus enim posuere eu. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
example.qmd
[Link with href]{.btn .btn-primary role="button" title="Here's a tooltip" data-bs-toggle="collapse" href="#collapseExample" aria-expanded="false" aria-controls="collapseExample"}:::: {#collapseExample .collapse}::: {.card .card-body}Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis sagittis posuere ligula sit amet lacinia. Duis dignissim pellentesque magna, rhoncus congue sapien finibus mollis. Ut eu sem laoreet, vehicula ipsum in, convallis erat. Vestibulum magna sem, blandit pulvinar augue sit amet, auctor malesuada sapien. Nullam faucibus leo eget eros hendrerit, non laoreet ipsum lacinia. Curabitur cursus diam elit, non tempus ante volutpat a. Quisque hendrerit blandit purus non fringilla. Integer sit amet elit viverra ante dapibus semper. Vestibulum viverra rutrum enim, at luctus enim posuere eu. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.:::::::
3.1 Horizontal Collapsing
[Button with horizontal collapse]{.btn .btn-primary type="button" title="Here's a tooltip" data-bs-toggle="collapse" data-bs-target="#collapseWidthExample" href="#collapseWidthExample" aria-expanded="false" aria-controls="collapseWidthExample"}::::: {style="min-height: 120px;"}:::: {#collapseWidthExample .collapse .collapse-horizontal}::: {.card .card-body style="width: 500px;"}Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis sagittis posuere ligula sit amet lacinia. Duis dignissim pellentesque magna, rhoncus congue sapien finibus mollis. Ut eu sem laoreet, vehicula ipsum in, convallis erat. Vestibulum magna sem, blandit pulvinar augue sit amet, auctor malesuada sapien. Nullam faucibus leo eget eros hendrerit, non laoreet ipsum lacinia. Curabitur cursus diam elit, non tempus ante volutpat a. Quisque hendrerit blandit purus non fringilla. Integer sit amet elit viverra ante dapibus semper. Vestibulum viverra rutrum enim, at luctus enim posuere eu. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.::::::::::::
Button with horizontal collapse
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis sagittis posuere ligula sit amet lacinia. Duis dignissim pellentesque magna, rhoncus congue sapien finibus mollis. Ut eu sem laoreet, vehicula ipsum in, convallis erat. Vestibulum magna sem, blandit pulvinar augue sit amet, auctor malesuada sapien. Nullam faucibus leo eget eros hendrerit, non laoreet ipsum lacinia. Curabitur cursus diam elit, non tempus ante volutpat a. Quisque hendrerit blandit purus non fringilla. Integer sit amet elit viverra ante dapibus semper. Vestibulum viverra rutrum enim, at luctus enim posuere eu. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
---title: "Moving My Website to Quarto"author: "Jihong Zhang"date: "06/25/2023"date-modified: "`{r} Sys.Date()`"draft: falsecategories: - quartoformat: html: toc: true toc-expand: 2 # expand to level 2 code-fold: false # hide code by default code-overflow: wrap---::: objectives## Overview {.unnumbered}Since June 25, 2023, I start to move my website from hugo/rmarkdown/blogdown/wowchemy to quarto website. It is difficult to explain why I spend so much time on that. Perhaps because some reasons same as other bloggers: 1. Quarto is the next generation of rmarkdown. 2. Quarto is independent with R or Rstudio. 3. Quarto has a clean file tree for website building. 4. Quarto has cleaner command than hugo (i.e., `quarto publish netlify` for publishing website etc.).This blog serves as a note how I customize quarto website bit by bit. It will not be a comprehensive tutorial (much online resources exists) but contain be some tricks.:::## Useful links {#useful-links}1. Quarto official documentation is always the best place to starts with.[{fig-align="center"}](https://quarto.org)2. Nicola Rennie's blog is very inspiring. Nice font setting and background. I feel like [Hugo Apéro](https://github.com/hugo-apero/) is the best hugo theme in the market.[{width="320" height="200"}](https://nrennie.rbind.io)3. Yihui's blog. As the creator of blogdown, Yihui talked about why not transfer to Quarto :P I am a old player of hugo/blogdown, but I am not good at customizing the website from the scratch. Thus, quarto suits my needs very well. For those who is very experienced at JS, hugo is still a better choice.[{width="320" height="200"}](https://yihui.org/en/2022/04/quarto-r-markdown/#should-you-switch)4. Frank Harrel's blog: R workflow.[{width="320" height="200"}](https://www.fharrell.com/post/rflow/)5. Silvia Canelón's blog: Hello Quarto: Porting my Website from Hugo Apéro[{width="320" height="200"}](https://silviacanelon.com/blog/2023-09-29-hello-quarto/)## Tricks of Quarto### Code highlightingThe very first trick is using `format > html > code-fold: true` settings in YAML metadata in *\_quarto.yml* (global) or *.qmd* (local) to hide the code block as `|> Code`, like:```{r}library(kableExtra)kbl(head(iris)) |>kable_styling(html_font ="Ysabeau Office",font_size =11, full_width =TRUE)```Note that the code block can be numbered and added with a left border using `code-block-bg: true` and `code-block-border-left: "#31BAE9"`Code block now also can be shown with language `#| echo: fenced`. As the code chunk shown below, `{r}` is explicitly presented. I don't hate `#|` as the new way of chuck option setup but when I test the code chuck, I found there is a space between `#|` and option keys. For example, it should be `#| echo: fenced` rather than `#|echo:fenced`. Otherwise, quarto will ignore chunk options.```{r}#| echo: fenced#| eval: false#| code-fold: falsekableExtra::kbl(head(iris)) |> kableExtra::kable_styling(html_font ="Ysabeau Office",bootstrap_options =c('striped', 'hover'),font_size =10, full_width =TRUE)``````{python}#| echo: fenced#| eval: false#| code-fold: showimport numpy as npiris = np.array(iris)```### Visual modelVisual model is one of the most appealing feature for Quarto but I am far from a expert in that. It looks like a visual model version of markdown editor (so called WYSIWYM editing, What you see is What you mean) but slightly different. The shortcut of switching between source and visual model is `Cmd` + `Shift` + `F4` (Thanks to Yihui's [JS](https://yihui.org/en/2023/02/key-buttons/) for pretty keyboard styling).::: callout-note {#keyborad} \## Keyboard ShortcutYou can use Shortcodes [keyboard shortcuts](https://quarto.org/docs/authoring/markdown-basics.html#keyboard-shortcuts) to display keyboard keys. For example, insert `{{{< kbd K >}}}` into Quarto documents displays {{< kbd K >}}. `{{{< kbd Shift-Ctrl-P >}}}` display {{< kbd Shift-Ctrl-P >}} after rendering. :::I list some most frequently used keyboard for visual mode editing:(a) Insert Hyperlink: `Cmd` + <kbd>K</kbd>(b) Add footnote[^1]: `Shift`+`Cmd`+`F7`(c) Insert picture: `Shift` +`Cmd` +<kbd>I</kbd>(d) Insert code chunk[^2]: `Alt` +`Cmd` +<kbd>I</kbd>(e) Edit attribute[^3]: `F4`[^1]: Like this.[^2]: By default, it will insert R code chunk. If another language is frequently, use `Tools > Modify keyboard shortcuts > filter 'Insert'`. There should be a place for setting shortcut for other language.[^3]: Click \`F4\` in any place in the div works.Please also refer to the [official document](https://quarto.org/docs/visual-editor/vscode/) for more shortcuts and features. One thing I found very interesting is single quote mark `` ` `` . First, I'm not sure how to escape this in visual model. Second, if you close quote before typing content, like \`\`, visual mode will escape both quote marks. However, if you type in left quote mark then content and then close quote (i.e., type in\``something` first, and type closing quote mark), it can quote content correctly.Last but not least, perhaps just type `/` in rstudio is a better choice as it will pop up a list of elements to choose.### giscus comments box theme toggle::: callout-importantnot work any more for Quarto 1.5.23:::giscus comments box needs some tweaks to switch light/dark based on the toggle switcher of quarto. Please find [Ella's post](https://ellakaye.co.uk/posts/2022-12-11_welcome-quarto/#giscus-comments-box-lightdark-toggle) and [Ella's giscus issue discussion](https://github.com/giscus/giscus/issues/336#issuecomment-1214401296) and [original Javascript](https://github.com/giscus/giscus/issues/336#issuecomment-1214366281).```{html, filename="giscus-mode-toggle.html"}<script>function getGiscusTheme(){const quartoTheme = localStorage.getItem("quarto-color-scheme");const giscusTheme = quartoTheme ==="alternate"?"dark":"light";return giscusTheme;}function setGiscusTheme(){ function sendMessage(message){const iframe = document.querySelector('iframe.giscus-frame');if(!iframe)return; iframe.contentWindow.postMessage({ giscus: message },'https://giscus.app');} sendMessage({ setConfig:{ theme: getGiscusTheme(),},});}document.addEventListener('DOMContentLoaded', function (){const giscusAttributes ={"src":"https://giscus.app/client.js","data-repo":"[ENTER REPO HERE]","data-repo-id":"[ENTER REPO ID HERE]","data-category":"[ENTER CATEGORY NAME HERE]","data-category-id":"[ENTER CATEGORY ID HERE]","data-mapping":"pathname","data-strict":"0","data-reactions-enabled":"1","data-emit-metadata":"0","data-input-position":"top","data-theme": getGiscusTheme(),"data-lang":"en","crossorigin":"anonymous","async":"",};// Dynamically create script tagconst giscusScript = document.createElement("script"); Object.entries(giscusAttributes).forEach(([key, value])=> giscusScript.setAttribute(key, value)); document.body.appendChild(giscusScript);// Update giscus theme when theme switcher is clickedconst toggle = document.querySelector('.quarto-color-scheme-toggle');if(toggle){ toggle.addEventListener('click', setGiscusTheme);}});</script>``````{html, filename="div-giscus.html"}<div class="giscus">`````` yamlinclude-in-header: giscus-mode-toggle.htmlinclude-after-body: div-giscus.html```::: callout-note## NoteRemember comment out giscus setting in \_quarto.yml``` yaml#comments:# giscus:# repo: JihongZ/quarto-academic-jihong```:::## Collapsing ButtonThere is no direct way to display a collapsing button in quarto. I found a way to do that by using bootstrap collapse component. The following code is a simple example of a collapsing button. The button is linked to a collapse component with the id `collapseExample`. When the button is clicked, the collapse component is shown or hidden.For more details of bootstrap collapse component, please refer to the [official documentation](https://getbootstrap.com/docs/5.3/components/collapse/).[Link with href]{.btn .btn-primary role="button" title="Here's a tooltip" data-bs-toggle="collapse" href="#collapseExample" aria-expanded="false" aria-controls="collapseExample"}:::: {#collapseExample .collapse}::: {.card .card-body}{{< lipsum 1 >}}:::::::``` {.markdown filename="example.qmd"}[Link with href]{.btn .btn-primary role="button" title="Here's a tooltip" data-bs-toggle="collapse" href="#collapseExample" aria-expanded="false" aria-controls="collapseExample"}:::: {#collapseExample .collapse}::: {.card .card-body}{{< lipsum 1 >}}:::::::```### Horizontal Collapsing``` markdown[Button with horizontal collapse]{.btn .btn-primary type="button" title="Here's a tooltip" data-bs-toggle="collapse" data-bs-target="#collapseWidthExample" href="#collapseWidthExample" aria-expanded="false" aria-controls="collapseWidthExample"}::::: {style="min-height: 120px;"}:::: {#collapseWidthExample .collapse .collapse-horizontal}::: {.card .card-body style="width: 500px;"}{{< lipsum 1 >}}::::::::::::```[Button with horizontal collapse]{.btn .btn-primary type="button" title="Here's a tooltip" data-bs-toggle="collapse" href="#collapseWidthExample" aria-expanded="false" aria-controls="collapseWidthExample"}::::: {style="min-height: 120px;"}:::: {#collapseWidthExample .collapse .collapse-horizontal}::: {.card .card-body style="width: 500px;"}{{< lipsum 1 >}}::::::::::::## Dropdown Menu::: {.dropdown}[Dropdown button]{.btn .btn-secondary .dropdown-toggle type="button" data-bs-toggle="dropdown" aria-expanded="false"}::: dropdown-menu- [Action]{.dropdown-item}- [Another action]{.dropdown-item}- [Something else here]{.dropdown-item}::::::```{=html}<div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> Table of Contents </button> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="#useful-links">Useful Link</a></li> <li><a class="dropdown-item" href="#keyborad">Keyboard Shortcut</a></li> </ul></div>`````` html<div class="dropdown"><button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> Table of Contents</button><ul class="dropdown-menu"><li><a class="dropdown-item" href="#useful-links">Useful Link</a></li><li><a class="dropdown-item" href="#keyborad">Keyboard Shortcut</a></li></ul></div>```