#R code blocks will look like this.
This is how I created this website for the SWELTR temperature manipulation experiment using a) Quarto to build the site and b) GitHub Pages to host the site.
This tutorial assumes you have a) git installed, b) a GitHub account, c) RStudio installed, and d) Quarto for R installed.
You will need to jump back and forth between the RStudio IDE and a terminal. You can use the terminal in RStudio if you wish, it is up to you.
I will try to point out which code you run in the RStudio console and which you run in a terminal. I will use different code block colors to help you differentiate between the two.
When you see a code block that looks like this, the command(s) must be executed in the RStudio console.
When you see a code block that looks like this, the command(s) must be executed in a terminal.
#Terminal code will look like this.
Overview
There are two main options for a GitHub Pages website.
- A user or organization site.
- A project site.
The difference between the two is that a user or organization site is a single site, like https://microbes.github.io/, and individual pages on this site are indexed like so:
https://microbes.github.io/about.html.
A project site on the other hand is like a collection of sites within a main site. A project site would have the same root URL (e.g., https://microbes.github.io/) but each project would have it’s own unique extension, like these examples:
https://microbes.github.io/deep-sea/ or https://microbes.github.io/forest-soils/.
Individual pages within a project site would be indexed like this: https://microbes.github.io/deep-sea/about.html
As mentioned above, the instructions here are for a GitHub Pages project site.
For more information see the GitHub Pages documentation. You can also check out A guide to using Github Pages.
Key Steps
Here is an overview of what we will be doing in this tutorial:
- Create organization on GitHub.
- Create two GitHub repos for the site, one to host the organization URL and another to host the raw code plus the
gh-pages
branch. - Clone the code repo to your computer.
- Create a
gh-pages
branch. - Build the initial site with Quarto for R.
- Customize the default
_quarto.yml
file. - Rebuild the site.
- Push changes to GitHub.
1. GitHub Setup
Create organization on GitHub
If you already have an organization skip to the next step.
a) In the upper right-hand corner of your GitHub page click on your avatar and select Your organizations
.
b) On the page that opens, hit New organization
.
c) Next, give your organization a name, provide an email address, and indicate whether this is for a personal or institutional account. Then hit Next
.
The name of the organization does not need to be the same as the website you create later.
d) Here you can add members. For now, just hit Complete setup
.
Create repos for the site
In this section, we need to create two repositories for the site: i) one to host the organization URL (i.e., https://sweltr.github.io/) and ii) another to host the raw code (e.g. .qmd
files) plus the gh-pages
branch. More on that in a minute. I am including instructions for things you MUST do in order to get the rest of the tutorial to work properly.
a) Hit the Create a new repository button
.
b) First, we create the github.io repo to host the main site.
There are a few things to do here:
- Name the repo, Here we call it
sweltr.github.io
. it doesn’t matter what you call this but it must be unique and have the.github.io
extension. - Make sure repo is public.
- You must Initialize this repository with a README File.
- Hit the
Create repository
button. This creates themain
branch of the repo.
Note: you can host a site on GitHub without the
github.io
extension but that is a more advanced skill and beyond the scope of this tutorial.
c) Next, we create the build repo to host the project source code. These steps are similar to those described above.
- Name the repo, here we call it
high-temp
. This will be the extension of the project site. So this project’s URL will be https://sweltr.github.io/high-temp/. - Make sure the repo is public.
- You must Initialize this repository with a README File.
- Hit the
Create repository
button. This creates themain
branch of the repo.
Note: you can make these repos private, however that is a bit more advanced and beyond the scope of the tutorial provided here :)
Review
Here is what we have so far:
An organization at https://github.com/sweltr/ that contains 2 repos, one for the GitHub Pages root URL, https://github.com/sweltr/sweltr.github.io and another for the source code, https://github.com/sweltr/high-temp. At this point both repos should only contain README
files.
We also have two URLs, one for the organiztion site (https://sweltr.github.io/) and another for the project site (https://sweltr.github.io/high-temp/).
2. Local Setup
Now that we have the main pieces in place of GitHub, it is time to setup everything on our local machine.
Clone the Code Repo
Let’s take a look at the high-temp
repo page. There are two important things to point out. First, in the upper left corner is a box that says main
. This is the primary branch for the repo and contains the source code for the site build (e.g., the .qmd
files). This will become important in a moment when we create a branch called gh-pages
that will link the build files (e.g., .html
files) to the organization URL. More on that in a minute.
First, we need to clone the high-temp
repo from GitHub to our local machine. There are several ways to do this, but I will show you how I do it. Navigate to the repo page. At the time of creation, it looked like this:
See the green button that says Code
. Click on that button and copy the URL.
Open a terminal window and navigate to a place where you want the repo to live on your computer. We will use the command git clone
with the URL you just copied. Run the clone command and then cd
into the directory.
git clone https://github.com/sweltr/high-temp.git
cd high-temp/
Now have a look at the contents of the directory using the ls
command. We want to append the command with the -al
flag. The l
option provides extended details about each file/directory and the a
option lists hidden files—files/directories that begin with a period and are hidden by default.
ls -al
So we have the README.md
file that was generated when we created the repo and a hidden directory called .git
. The .git
directory is super, super important because this is how the remote repo (on GitHub) and the local repo (on your computer) keep track of changes.
total 8
drwxr-xr-x@ 4 scottjj 923590601 128 May 13 08:25 .
drwxr-xr-x@ 5 scottjj 923590601 160 May 13 08:25 ..
drwxr-xr-x@ 12 scottjj 923590601 384 May 13 08:25 .git
-rw-r--r--@ 1 scottjj 923590601 11 May 13 08:25 README.md
Create a gh-pages branch
Great. We have the high-temp
repo cloned on our local machine. For historical reason, a GitHub Pages site needs to be built to a directory called public/
. But we do not need to upload the public/
build directory to the main
branch on our repo. So, we are going to create a .gitignore
file and add public/
to that file. The .gitignore
tells git
to ignore whatever is listed in that file when it pushes local changes to the remote repository. As you build your site, you will need to add additional items to the .gitignore
file.
echo public/ >> .gitignore # Add items as needed.
If you run ls -al
again you should see the .gitignore
file is now listed in the directory. If you type nano .gitignore
you can see the contents of the file.
OK, now let’s push the changes we made to the local branch (origin
) to the remote branch (main
). First, run:
git status
Hopefully you see the .gitignore
file listed in red along with some other details. This means there are untracked files in your repo. Go ahead and run:
git add --all
git status
Now you should see the same files in green. This means the files are staged and ready to commit. Now run:
git commit -a -m "initial commit"
git push origin main
If everything worked OK, your files have been pushed to the GitHub repo. Have a look at the code repo on GitHub to confirm your changes have been pushed.
Now, it is important that there is no public/
directory yet. Just to make sure there is no public/
directory, we can run the remove command in our terminal.
rm -rf public
Now we go through the steps to create the the gh-pages
branch.
git checkout --orphan gh-pages
Switched to a new branch 'gh-pages'
git reset --hard
git commit --allow-empty -m "Initializing gh-pages branch"
[gh-pages (root-commit) fd6028a] Initializing gh-pages branch
git push origin gh-pages
Enumerating objects: 2, done.
Counting objects: 100% (2/2), done.
Writing objects: 100% (2/2), 180 bytes | 180.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0), pack-reused 0
remote:
remote: Create a pull request for 'gh-pages' on GitHub by visiting:
remote: https://github.com/sweltr/high-temp/pull/new/gh-pages
remote:
To https://github.com/sweltr/high-temp.git
* [new branch] gh-pages -> gh-pages
git checkout main
Enumerating objects: 2, done.
Counting objects: 100% (2/2), done.
Writing objects: 100% (2/2), 180 bytes | 180.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0), pack-reused 0
remote:
remote: Create a pull request for 'gh-pages' on GitHub by visiting:
remote: https://github.com/sweltr/high-temp/pull/new/gh-pages
remote:
To https://github.com/sweltr/high-temp.git
* [new branch] gh-pages -> gh-pages
(base) high-temp: scottjj$ git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
git worktree add -B gh-pages public origin/gh-pages
Preparing worktree (resetting branch 'gh-pages'; was at fd6028a)
Branch 'gh-pages' set up to track remote branch 'gh-pages' from 'origin'.
HEAD is now at fd6028a Initializing gh-pages branch
Now run the following to see what is in the repo directory.
ls -al
drwxr-xr-x@ 6 scottjj 923590601 192 May 13 08:41 .
drwxr-xr-x@ 5 scottjj 923590601 160 May 13 08:25 ..
drwxr-xr-x@ 14 scottjj 923590601 448 May 13 08:41 .git
-rw-r--r--@ 1 scottjj 923590601 8 May 13 08:40 .gitignore
-rw-r--r--@ 1 scottjj 923590601 11 May 13 08:40 README.md
drwxr-xr-x@ 3 scottjj 923590601 96 May 13 08:41 public
There should now be a public/
directory. Run the following to make sure this is a .git
directory.
ls -al public/
total 8
drwxr-xr-x@ 3 scottjj 923590601 96 May 13 08:41 .
drwxr-xr-x@ 6 scottjj 923590601 192 May 13 08:41 ..
-rw-r--r--@ 1 scottjj 923590601 104 May 13 08:41 .git
Review
At this point all the pieces are in place to build your site and host it on GitHub. In addition to the repos you have on GitHub, you should have a local directory of the code repo, in our case it is called high-temp
. In this directory there should be a README.md
file, a .gitignore
file, a .git
directory, and the public/
directory.
3. Site Build
Time to build the site. As mentioned in the intro, we will use Quarto to create the website. To keep things simple, we will generate the initial site in a temporary directory and copy the files to the git formatted directory at the end.
Open RStudio and hit File >> New Project
. In the pop-up window hit New Project
.
Then in the New Project Wizard select the New Directory
option.
Under Project Type, scroll down until you see Quarto Website
and select that option.
Give the Directory a name and hit Create Project
. Consider this an intermediate step in the process. We need to create a project directory to generate the initial site. Eventually we will copy all of these file to the directory of the repo we cloned earlier. You can call this something like web
if you wish, it doesn’t really matter since this is only a temporary directory.
Now, if everything worked OK, you should see that five files were created and two of the files are open in your RStudio IDE.
– index.qmd
. This is the landing page of your site. This file is the first thing people see when they navigate to your site.
– _quarto.yml
. This is a YAML file and is used to configure your site. DO NOT erase this file.
In fact, we need to edit the _quarto.yml
file to configure it for our site. As you move further into building your site, you will need to make many modifications to this file. For now however, we will just focus on the minimum changes you need to make to get your site online. Go ahead and click on that file. This is what the default file looks like.
First, below the title
line (nested under website
) add the following lines.
site-url: https://sweltr.github.io/high-temp/
repo-url: https://github.com/sweltr/high-temp/
The site-url
is the .github.io
URL we created way back when we created the site repo. The repo-url
is the repo we created to host the project source code.
When you build or render your site, RStudio will dump all the site files (e.g., .html
files) in the output_dir
. The default output directory is _site
, which RStudio generates when you render the site for the first time. I see no reason why you cannot leave the build directory as is but I prefer to call mine public_build/
. Go ahead and add a line of the _quarto.yml
file specifying the output-dir
. This should be nested under project
like so:
project:
type: website
output-dir: public_build
Great. One last thing to do. When you render your site, RStudio will try to add everything in the main directory to the output directory, in this case public_build/
. There are many cases where this is not desirable. For example, let’s say we have you have a directory called sequence_data
that contains a bunch of fastq
files. We do not need these files to build the site (and we probably do not want these on GitHub) so we need to tell RStudio to ignore these files when it builds the site. For that, we add the line render
nested under project
. Here we can specify what is, and is not, rendered when the site is build. As you get deeper into building your site, you will likely have many files/directories that you want excluded.
Don’t get confused here. The
render
line in the_quarto.yml
file is different than the.gitignore
file discussed earlier. They do completely different things. If this is unclear, go back and review the section on the.gitignore
file.
For now, we will focus on the necessary things to include and exclude from the build. Items must be listed on separate lines, in double quotes. So let’s say we want to render all .qmd
files but ignore a few directories. The way to code this is that anything we want to exclude should begin with an exclamation point (!
). Go ahead and add these lines.
project:
type: website
output-dir: public_build
render:
- "*.qmd"
- "!public/"
- "!public_build/"
OK, a little explanation. The first thing we need to exclude in the actual build directory public_build/
(or _site
if you kept the default). If we do not include this, RStudio will get stuck in a loop where it continues to add public_build/
to the public_build/
directory. Next, remember that to host a gh-pages site, the build files (e.g., the .html
files) must be in a directory called public/
. We created this directory when we created the gh-pages
branch.
So why don’t we just make the buld directory
public/
instead ofpublic_build/
or_site/
?
Good question. The reason is that public/
is a special directory that contains git related files (hidden by default). When we render a site, RStudio will first overwrite the output directory, thereby deleting the .git
files, and then recreate the output directory add the new build files. This is not cool. To avoid this, we use an intermediate output directory, public_build/
(or whatever you call it), to generate the site. Than we can copy all the files from the output directory to the public/
directory without losing the git
info. This is a little cumbersome but I have not yet found a workaround. This is still an issue as of this writing.
If you changed the name of the default build directory, go ahead and remove the default directory now. In your terminal type:
rm -r _site
Now, save all of your changes to the _quarto.yml
file and in the RStudio Console run the following:
quarto::quarto_render()
You should see a new directory called public_build/
. Open that folder and double-click on index.html
. The homepage of your new site should open in your default browser.
Review
Sweet. Let’s review what we have so far. From the 1. GitHub Setup we created two repos, one to host the .github.io
organization and another to host the raw code (e.g. .qmd files) plus the gh-pages branch. In 2. Local Setup we cloned the code repo and create a gh-pages branch in a directory called public/
. In 3. Site Build we generated an initial site within a dummy directory, modified the _quarto.yml
file, and re-rendered the site to an output directory called public_build/
Integration
Time to push our changes to GitHub. The first step is to copy all of the files in your dummy site directory to the directory of the cloned repo (high-temp
).
First, in your terminal, navigate to the cloned repo directory. Use the pwd
command to confirm your location.
pwd
/Users/scottjj/Dropbox (Smithsonian)/GITHUB_PROJECTS/SWELTR/high-temp
Assuming your directory structure setup is similar to the image above, next run the following to copy all of the files.
cp -r ../dummy/* .
Now take a look at the contents of the current working directory.
ls -al
It should look something like this:
drwxr-xr-x 14 scottjj 923590601 448 May 13 09:18 .
drwxr-xr-x@ 7 scottjj 923590601 224 May 13 09:15 ..
-rw-r--r--@ 1 scottjj 923590601 6148 May 13 09:18 .DS_Store
-rw-r--r-- 1 scottjj 923590601 50 May 13 09:18 .Rhistory
drwxr-xr-x 4 scottjj 923590601 128 May 13 09:18 .Rproj.user
drwxr-xr-x@ 14 scottjj 923590601 448 May 13 08:41 .git
-rw-r--r--@ 1 scottjj 923590601 8 May 13 08:40 .gitignore
-rw-r--r--@ 1 scottjj 923590601 11 May 13 08:40 README.md
-rw-r--r-- 1 scottjj 923590601 202 May 13 09:18 _quarto.yml
-rw-r--r-- 1 scottjj 923590601 58 May 13 09:18 about.qmd
-rw-r--r-- 1 scottjj 923590601 145 May 13 09:18 index.qmd
-rw-r--r-- 1 scottjj 923590601 17 May 13 09:18 styles.css
drwxr-xr-x@ 3 scottjj 923590601 96 May 13 08:41 public
drwxr-xr-x 7 scottjj 923590601 224 May 13 09:18 public_build
-rw-r--r-- 1 scottjj 923590601 225 May 13 09:18 web.Rproj
At this point we need to do a few final housekeeping tasks. First, let’s add a few additional files to the .gitignore
file.
Run this command in your terminal. You should only see the public/
directory listed.
nano .gitignore
Add the following lines, save the file, and exit nano
.
.Rproj.user
.Rhistory
.RData
.Ruserdata
.Rapp.history
.DS_Store
web.Rproj
public_build/
Now, copy all of the files from public_build/
to public/
.
cp -r public_build/* public/
Then move into the public/
directory and run git status
.
cd public
git status
All the untracked or changed files should be in red.
On branch gh-pages
Your branch is up to date with 'origin/gh-pages'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
about.html
index.html
search.json
site_libs/
sitemap.xml
nothing added to commit but untracked files present (use "git add" to track)
Now add the files to be committed and check the status again.
git add --all
git status
All the untracked or changed files should now be green.
On branch gh-pages
Your branch is up to date with 'origin/gh-pages'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: about.html
new file: index.html
new file: search.json
new file: site_libs/anchor-4.2.2/anchor.min.js
new file: site_libs/autocomplete-0.37.1/autocomplete.min.js
new file: site_libs/bowser-1.9.3/bowser.min.js
new file: site_libs/distill-2.2.21/template.v2.js
new file: site_libs/font-awesome-5.1.0/css/all.css
new file: site_libs/font-awesome-5.1.0/css/v4-shims.css
new file: site_libs/font-awesome-5.1.0/webfonts/fa-brands-400.eot
new file: site_libs/font-awesome-5.1.0/webfonts/fa-brands-400.svg
new file: site_libs/font-awesome-5.1.0/webfonts/fa-brands-400.ttf
new file: site_libs/font-awesome-5.1.0/webfonts/fa-brands-400.woff
new file: site_libs/font-awesome-5.1.0/webfonts/fa-brands-400.woff2
new file: site_libs/font-awesome-5.1.0/webfonts/fa-regular-400.eot
new file: site_libs/font-awesome-5.1.0/webfonts/fa-regular-400.svg
new file: site_libs/font-awesome-5.1.0/webfonts/fa-regular-400.ttf
new file: site_libs/font-awesome-5.1.0/webfonts/fa-regular-400.woff
new file: site_libs/font-awesome-5.1.0/webfonts/fa-regular-400.woff2
new file: site_libs/font-awesome-5.1.0/webfonts/fa-solid-900.eot
new file: site_libs/font-awesome-5.1.0/webfonts/fa-solid-900.svg
new file: site_libs/font-awesome-5.1.0/webfonts/fa-solid-900.ttf
new file: site_libs/font-awesome-5.1.0/webfonts/fa-solid-900.woff
new file: site_libs/font-awesome-5.1.0/webfonts/fa-solid-900.woff2
new file: site_libs/fuse-6.4.1/fuse.min.js
new file: site_libs/header-attrs-2.11/header-attrs.js
new file: site_libs/headroom-0.9.4/headroom.min.js
new file: site_libs/jquery-3.6.0/jquery-3.6.0.js
new file: site_libs/jquery-3.6.0/jquery-3.6.0.min.js
new file: site_libs/jquery-3.6.0/jquery-3.6.0.min.map
new file: site_libs/popper-2.6.0/popper.min.js
new file: site_libs/tippy-6.2.7/tippy-bundle.umd.min.js
new file: site_libs/tippy-6.2.7/tippy-light-border.css
new file: site_libs/tippy-6.2.7/tippy.css
new file: site_libs/tippy-6.2.7/tippy.umd.min.js
new file: site_libs/webcomponents-2.0.0/webcomponents.js
new file: sitemap.xml
Commit the files.
git commit -m "Publishing to gh-pages initial commit"
[gh-pages f30f1ff] Publishing to gh-pages initial commit
37 files changed, 22182 insertions(+)
create mode 100644 about.html
create mode 100644 index.html
create mode 100644 search.json
create mode 100644 site_libs/anchor-4.2.2/anchor.min.js
create mode 100644 site_libs/autocomplete-0.37.1/autocomplete.min.js
create mode 100644 site_libs/bowser-1.9.3/bowser.min.js
create mode 100644 site_libs/distill-2.2.21/template.v2.js
create mode 100644 site_libs/font-awesome-5.1.0/css/all.css
create mode 100644 site_libs/font-awesome-5.1.0/css/v4-shims.css
create mode 100644 site_libs/font-awesome-5.1.0/webfonts/fa-brands-400.eot
create mode 100644 site_libs/font-awesome-5.1.0/webfonts/fa-brands-400.svg
create mode 100644 site_libs/font-awesome-5.1.0/webfonts/fa-brands-400.ttf
create mode 100644 site_libs/font-awesome-5.1.0/webfonts/fa-brands-400.woff
create mode 100644 site_libs/font-awesome-5.1.0/webfonts/fa-brands-400.woff2
create mode 100644 site_libs/font-awesome-5.1.0/webfonts/fa-regular-400.eot
create mode 100644 site_libs/font-awesome-5.1.0/webfonts/fa-regular-400.svg
create mode 100644 site_libs/font-awesome-5.1.0/webfonts/fa-regular-400.ttf
create mode 100644 site_libs/font-awesome-5.1.0/webfonts/fa-regular-400.woff
create mode 100644 site_libs/font-awesome-5.1.0/webfonts/fa-regular-400.woff2
create mode 100644 site_libs/font-awesome-5.1.0/webfonts/fa-solid-900.eot
create mode 100644 site_libs/font-awesome-5.1.0/webfonts/fa-solid-900.svg
create mode 100644 site_libs/font-awesome-5.1.0/webfonts/fa-solid-900.ttf
create mode 100644 site_libs/font-awesome-5.1.0/webfonts/fa-solid-900.woff
create mode 100644 site_libs/font-awesome-5.1.0/webfonts/fa-solid-900.woff2
create mode 100644 site_libs/fuse-6.4.1/fuse.min.js
create mode 100644 site_libs/header-attrs-2.11/header-attrs.js
create mode 100644 site_libs/headroom-0.9.4/headroom.min.js
create mode 100644 site_libs/jquery-3.6.0/jquery-3.6.0.js
create mode 100644 site_libs/jquery-3.6.0/jquery-3.6.0.min.js
create mode 100644 site_libs/jquery-3.6.0/jquery-3.6.0.min.map
create mode 100644 site_libs/popper-2.6.0/popper.min.js
create mode 100644 site_libs/tippy-6.2.7/tippy-bundle.umd.min.js
create mode 100644 site_libs/tippy-6.2.7/tippy-light-border.css
create mode 100644 site_libs/tippy-6.2.7/tippy.css
create mode 100644 site_libs/tippy-6.2.7/tippy.umd.min.js
create mode 100644 site_libs/webcomponents-2.0.0/webcomponents.js
create mode 100644 sitemap.xml
And finally push the files to the gh-pages branch.
git push origin gh-pages
Enumerating objects: 55, done.
Counting objects: 100% (55/55), done.
Delta compression using up to 8 threads
Compressing objects: 100% (45/45), done.
Writing objects: 100% (54/54), 1.37 MiB | 348.00 KiB/s, done.
Total 54 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/sweltr/high-temp.git
fd6028a..f30f1ff gh-pages -> gh-pages
Do the same for the build files. Make sure you back out of the public directory with the cd ../
command. This time you are pushing to the main
branch, not the gh-pages
branch.
cd ../
git status
git add --all
git status
git commit -m "Publishing to gh-pages initial commit"
git push origin main
Now head over to your GitHub code repo and look at the two branches to make sure everything looks good. In this case, https://github.com/sweltr/high-temp. You should see the main
branch of this repo—this contains all of the .qmd
files.
Find the button in the upper left that says main
. Click on that and select gh-pages
.
The gh-pages
branch contains all of the .html
files.
Wait a few minutes and navigate to your project webpage. In our case, https://sweltr.github.io/high-temp/.
You site should be LIVE!!!
Adding content
Most of the steps up to this point should only need to be done once. Now it is time to add content to your site, customize the look, etc. From this point forward, whenever you make changes that you want to make public, you need to do the following:
- Render the site.
quarto::quarto_render()
Or to build individual pages run:
quarto::quarto_render("new_page.qmd")
- Copy files from
public_build/
topublic/
cp -r public_build/* public/
- Commit and push the changes to the
gh-pages
branch.
cd public/
git status
git add --all
git status
git commit -m "added new page"
git push origin gh-pages
- Commit and push the changes to the
main
branch.
cd ../
git status
git add --all
git status
git commit -m "added new page"
git push origin main
Source Code
The source code for this page can be accessed on GitHub by clicking this link.
Last updated on
[1] "2022-06-29 07:25:59 EST"