In this part of the workshop, we will learn to create and customise a
webpage using {pkgdown}
for your R package
📦! We will also implement a GitHub Action to continuous integrate and
deploy the website via GitHub
pages
We will be using some very handy R tools today! Massive shout out to the contributors and maintainers for of {usethis}, {pkgdown} and r-lib/actions for making our lives easier! 👏👏👏
{pkgdown}
creates beautiful, static html
websites for your R package in a few steps. They are straight-forward to
configure and deployed using GitHub pages. If you would like to learn
more about {pkgdown}
I recommend having a good read of the
the official {pkgdown}
site - made with {pkgdown}
😉 Its one I always find
myself returning to!
Before we jump in, we have to make sure the following are installed/set up correctly!:
If you have both these set up, skip ahead
If not, click through the tabs below to set these up
First, we can check if we have git and PAT installed/set up correctly. You may have done so in previous projects! Your past self has your back! 🙏
usethis::git_sitrep()git_sitrep() # git situation report
If git and PAT has already been set up, we would see this under the bold heading GitHub:
If you don’t see this ⚠️ Follow the next tabs to git sorted 😉
git installation is via the shell terminal and is OS dependent, so take a look at this chapter of Happy git with R to get started!
I recommend having a good read of
?usethis::gh_token_help()
and follow the instructions
there
If you want more details, try the tl;dr section of the Happy Git and GitHub for the useR book and the subsequent chapters, these will get you on your feet in no time!
?usethis::gh_token_help()
This function will open up a browser for you to select the scopes you want to your PAT to do. The recommended scopes are already pre-selected for ya!
usethis::create_github_token()
If usethis::create_github_token()
fails, try this link
to create a PAT manually on the GitHub Website
Once you a PAT has been created for you, copy and save this in your password manager! For security reasons, you won’t get to see the PAT again if you close the browser! Now we will register your PAT using:
# install.packages("gitcreds")
gitcreds::gitcreds_set()
Once this is complete, just for peace of mind… check your git settings are OK!
usethis::git_sitrep() # git situation report
Lets go ahead and load the packages we need
If you haven’t already, lets load {devtools}
and
{pkgdown}
# install.packages("devtools", "pkgdown")
library(devtools) #Will load usesthis and roxgen2 as well
library(pkgdown)
Like many package dev tools, {usethis}
will assist you in configuring your package so you can build a slick
website! To initiate this process, run:
use_pkgdown()
Notice, how this function does a few things on your behalf:
^_pkgdown\\.yml$
, ^docs$
,
^pkgdown$
to .Rbuildignore
file.gitignore
file_pkgdown.yml
. This file controls the
overall structure and ‘look’ of your siteNow try this and be blown away 🤯
pkgdown::build_site()
This function sweeps through all your package and builds
.htmls
for the 3 main sections of your webpage:
👀 Note that if you only have one vignette and it’s named as your package name e.g. ‘ohwhaley.Rmd’, this will automatically be rendered as your ‘Getting Started’ page
⚠️ Did you get the warning?
OK so things in {pkgdown}
requires a slightly different
file organisation! No biggie! Any images e.g hex stickers or plots
generated in your documentation, needs to be stored either in
man/figures
or vignettes/
Go ahead and move these files manually in your Files Explorer or Finder 📨 and update any file paths in your documentation accordingly!
So, are you telling me I have to build_site()
every time
I want to make changes to my website?! Thankfully not 😉!
We can rely on the pkgdown
GitHub
Action workflow to continuously integrate the building and
deployment of our website. This is called a
CI/CD workflow to software devs. You only need to set
this up once!
Give it a try:
use_pkgdown_github_pages()
👀 Note: This function will ask if you want to
overwrite the existing _pkgdown.yml
. This
is totally okay since we haven’t made any substantial changes to the
file, but I would be mindful! Alternatively, you can abort the function,
commit your current changes and then proceed to run
use_pkgdown_github_pages
and allow it overwrite your
changes
This function does a few things for us with our PAT:
_pkgdown.yml
gh-pages
branch in your repo for
deployment. This keeps your repo organised so your
master/main
branch remains R package specific!_pkgdown.yml
,
DESCRIPTION
, homepage of your repor-lib/actions/examples/pkgdown.yaml@v2
in
your workflow folderNow commit and push these changes! Navigate to your repo and admire your work! 🖼
The wonderful thing about {pkgdown}
, is that it
eliminates double handling, you don’t need to write seperate files again
to build a website! You can directly make changes to your
documentation files and this will automatically update your
site! So what happens if you want to add more functions, or
update the contributor lists or want to fix a typo in existing
documentation? We can ultimately rely on the GHA we just set up, but
often we want to preview changes locally.
This is when you will become familiar with the build_XX()
functions. Let’s say that you’ve fixed a typo in your README, well
it is a bit of an overkill to build the entire site to materialise this
change? This is when you would use the more targeted
build_home()
function 🎯
These targeted build_XX()
functions can help streamline
a developer’s workflow, particularly if they are working on a very
comprehensive website with many Articles to render! There is certainly
nothing wrong with using build_site()
as a default (that is
what I do for simple packages)!
Below I’ve provided workflows for updating following files, notice
that I’ve used specific build_XX()
for each type of
documentation changes:
README
- Note if you are
using a README.Rmd
, remember to knit to regenerate its
fellow README.md
usethis::document()
pkgdown::build_home()
vignettes/
directory using
`usethis::usethis::document()
pkgdown::build_reference()
usethis::document()
usethis::build_vignettes()
pkgdown::build_articles()
So what if you want more Articles on your site for case studies, walk-throughs but don’t want to necessarily exported these as vignettes with your R package?
We can use:
usethis::use_article()
Similar to usethis::vignette()
, this will create a .Rmd
and store it in vignettes/articles/
. Once you are done
editing the .Rmd, use build_articles()
to preview your
work!
Now to the fun stuff! ⏭
Similar to a ggplot
, you can tweak almost
anything on your {pkgdown}
webpage. Below, I will go
through a few simple features to achieve a polished looking site. If you
require more specific styling, I recommend this
documentation on the {pkgdown} site.
The most efficient way to style your pkgdown site is to use Bootswatch themes. You can preview these theme here: https://bootswatch.com/
Once you have selected one you like, you can assign the name of the
theme as the bootswatch
parameter in your
_pkgdown.yml
url: https://fontikar.github.io/ohwhaley/
template:
bootstrap: 5
bootswatch: journal
I am going to go for the Journal
theme! I like the look
of the pink!
Now you quickly preview these changes without building the whole site by using:
build_home_index()
preview_site() # Opens new browser with recent changes
build_home_index()
runs faster than
build_home
as it ONLY builds the index.html
homepage. This will skip the building the authors
+
LICENSE
htmls which is handy if you want to quickly preview
your changes.
Hang on…why is my page not like the example in the preview? Why is my navbar…not pink?! (There are times I’ve tested this and it was BLUE!?)
Well generally, each Bootswatch theme has three background
(bg
) variations: light
, dark
and
primary
and two foreground (type
) variations:
light
and dark
{pkgdown}
will attempt to choose the correct colours for
bg
and type
according to the preview but
sometimes this doesn’t match. We can override the default navbar colour
palette by changing the values for bg
and type
as below:
url: https://fontikar.github.io/ohwhaley/
template:
bootstrap: 5
bootswatch: journal
navbar:
bg: primary
type: light
Repeat the build process for the home page but this time use
init_site()
. This implements your recent changes but
doesn’t open a new tab. To view your changes, hit Refresh
or Ctrl/Cmd+R - ta-da! 🎉
build_home_index()
init_site() # Implements changes
⚠️🐛 When I tested this section on a mac M1 machine and attempted to
override the default colours of the Journal theme….it turned blue! I end
up switching the theme entirely to something else
e.g. theme: cosmo
and built the site and made sure it
changed. After that, I reverted back to theme: journal
and
set the bg: primary
and type: light
and it
seemed to work again! Just flagging here in case it is consistent across
the workshop!
For larger, more complex packages that have many functions, it is often useful to group our functions in a logical, tidy way for the Reference section. For example, take a look at the {pkgdown} reference section.
We can tweak the Reference using the reference
field in
the _pkgdown.yml
You can add a title
or subtitle
to divide
your functions and provide it with an information using the
desc
field (description). Here is an example
from the {ohwhaley}
package so you can see what field
corresponds to what outcome:
navbar:
reference:
- title: Exported functions
desc: Whaley nice description
- contents:
- say
- subtitle: Where are whale puns stored
- contents:
- phrases
- title: Data
- contents:
- cetacean_data
👀 Note: I’ve included the navbar:
field so you see how the indents need to be formatted relative to the
other fields!
There are few handy functions teo help you select functions that share the same prefix or suffix:
starts_with("prefix")
to select these shared prefixes
e.g. join_all
, join_with
,
join_by
ends_with("suffix")
for shared suffixes
e.g. make_data
, change_data
,
bind_data
Have some utility functions that you don’t want to share in your
Reference section? No probs! Pop these using a section with the
title
field set to internal
.
👀 Note that there is NO
-
in front of the contents
field
navbar:
reference:
- title: internal
contents:
- phrases