install.packages('babelquarto', repos = c('https://ropensci.r-universe.dev', 'https://cloud.r-project.org'))
This is how we built this!
No place like home
This is a a personal website for jrfep, and it consists of multiple repositories.
How to make an entrance
I created a presentation using Reveal.js and placed it in my personal github repo: https://github.com/jrfep/jrfep.github.io. The README of that repo contains instruction for re-creating the intro presentation.
This now sits in the alpha-centaury
branch. Older versions of my site are available in other branches.
My other branch uses Jekyll (but I gave up on that some time ago, so do not expect any updates).
I also tried Rmarkdown for some time, might get back to that if this one does not work.
I was tempted to create a multi-lingual site using babelquarto:
But it was a short-lived experiment. I think it could work for simple sites, but would require more tweaks to make it work with my current site.
Multilingual
As you can read (or not), these instructions are in English, but this site has content in multiple languages… I know it is confusing, but this is how I work. If you require clarifications please open an issue or send me a message.
After much experimentation, I finally decided to open independent repos for my Spanish and English content.
Both repos use Quarto to build the sub-sites, and they are only connected by external links.
Libraries
To manage and update the version of libraries that we need, I used renv
for some iterations, but it was complex to keep version across machines and different OSs…
When we use renv
we need to run different commands, until all the changes have been synchronised1:
::init()
renv::status()
renv::install()
renv::status()
renv::snapshot() renv
But if we don’t update the .gitignore file things can get messy.
Render site
With Rmarkdown we could run this (in RStudio) to render site locally:
::render_site() rmarkdown
Or preview one file
::render_site("presentations.Rmd") rmarkdown
With quarto and RStudio we can open the Build tab and select Build Website…
Or we can go to the command line and render the site:
quarto render
Sing All the rowboats in the meantime (optional).
And then launch a preview:
quarto preview
If this work, we can just git add
, git commit
and git push
it to the repo and see the changes!
Font Awesome
They work well out of the box with Rmarkdown, but for quarto we need to install an extension.
Switch to the repository folder and checkout the git branch we are working on, and then:
quarto install extension quarto-ext/fontawesome
But I am using bootstrap icon in this site, so I did not activate this extension here.
Use {{< fa smile >}}
or {{< fa lemon >}}
in the text to show the fonts.
Just in case
Prepare data for some pages
Bibliography
For the bibliography, I downloaded one csl
as a base style:
cd bibteX
wget 'https://www.zotero.org/styles/journal-and-proceedings-of-the-royal-society-of-new-south-wales?source=1' --output-document=my.csl
Modify sort order of the bibliography (not the citation…):
bibliography hanging-indent="true" entry-spacing="0">
<sort>
<key variable="issued" sort="descending"/>
<key macro="author"/>
<sort>
</ ...
And voilà!
OSF data
::i_am("how2/how-to-site.qmd")
hereif (!require(osfr)) {
install.packages("osfr")
library(osfr)
}<- osf_retrieve_user("me") %>%
lst_osf osf_ls_nodes()
if (!dir.exists(here::here("data")))
dir.create(here::here("data"))
<- here::here("data","OSF-data.rds")
file_name saveRDS(file=file_name, lst_osf)
GitHub data
::i_am("how2/how-to-site.qmd")
hereif (!require(jsonlite)) {
install.packages("jsonlite")
library(jsonlite)
}<- read_json("https://api.github.com/orgs/red-list-ecosystem/repos")
gh_rle_org <- read_json("https://api.github.com/orgs/ces-unsw-edu-au/repos")
gh_ces_org <- read_json("https://api.github.com/users/jrfep/repos")
gh_jrfep # https://api.github.com/search/repositories?q=user:jrfep&fork:false
# for each repo query the languages_url and summarise the lines of code for each language
<- here::here("data","GitHub-data.rda")
file_name save(file=file_name, gh_rle_org, gh_ces_org, gh_jrfep)
Flexdashboard and iNaturalist
I use to have a dashboard here, but it works better with Rmarkdown than with quarto. SO I moved it to another site/repo.
There might be some alternatives in quarto for this, but haven’t tested them yet.
That OLD dashboard was inspired by this example: https://github.com/gonzalobravoargentina/inat_flexdashboard_ARG
To get the data I first install the rinat
package:
::i_am("how2/how-to-site.qmd")
hereif (!require(rinat)) {
install.packages("rinat")
library(rinat)
}
Then I can download the observations from iNaturalist and save them in a data folder:
# Download observations and save to RDS file
<- get_inat_obs_user("NeoMapas",maxresults = 5000)
user_obs if (!dir.exists(here::here("data")))
dir.create(here::here("data"))
<- here::here("data","iNaturalist-obs-NeoMapas.rds")
file_name saveRDS(file=file_name, user_obs)
To get the logo
With wget
and ImageMagick, it is easy to download and resize in the terminal (bash
) with two lines of code:
##mkdir
wget https://neomapas.github.io/assets/images/logo_NeoMapas_p.gif
magick logo_NeoMapas_p.gif -resize 100x148 resize_logo.gif
Photos from Flickr
So, I think I need some photos in my website, and I have a Flickr account, and I use R, there should be a library that…
Yes, there is!. And I actually wrote a blog-entry about this.
Photos from google
This took me a bit longer to figure out. Basically:
- I created a project in google cloud,
- enabled Photos Library API (not sure if this is relevant here),
- configured a simple consent page,
- created a OAuth 2.0 client ID and downloaded the json file.
- added
GC_PROJECT_EMAIL
andGC_PROJECT_CRED_JSON
to my .Renviron file - Then wrote some lines of code to do the authentication steps with library
gargle
and the queries with libraryhttr
.
I wrote a detailed, step-by-step explanation here.
This is the code…
library(gargle)
library(dplyr)
library(jsonlite)
library(httr)
library(foreach)
library(stringr)
readRenviron("~/.Renviron")
<- Sys.getenv("GC_PROJECT_CRED_JSON")
cred_json if (!file.exists(cred_json)) {
stop("credentials not found, please update Renviron file")
else {
} <- gargle_oauth_client_from_json(path=cred_json)
clnt
}
<- gargle2.0_token(
tkn email = Sys.getenv("GC_PROJECT_EMAIL"),
client = clnt,
scope = c("https://www.googleapis.com/auth/photoslibrary.readonly",
"https://www.googleapis.com/auth/photoslibrary.sharing")
)<- token_fetch(token=tkn)
k = paste('Bearer', k$credentials$access_token)
authorization
<-
getalbum GET("https://photoslibrary.googleapis.com/v1/albums",
add_headers(
'Authorization' = authorization,
'Accept' = 'application/json'),
query = list("pageSize" = 50)) %>%
content(., as = "text", encoding = "UTF-8") %>%
fromJSON(.)
if (!is.null(getalbum$nextPageToken)) {
<-
getalbum2 GET("https://photoslibrary.googleapis.com/v1/albums",
add_headers(
'Authorization' = authorization,
'Accept' = 'application/json'),
query = list("pageToken" = getalbum$nextPageToken)) %>%
content(., as = "text", encoding = "UTF-8") %>%
fromJSON(.)
}
<- getalbum$albums %>% select(id, title)
album_info #aIDs <- getalbum %>% filter(albums.shareInfo.isJoined) %>% pull(albums.id)
<- c("Lugares - México", "Lugares - Europa", "Lugares - Sur América", "Eventos - Venezuela")
lugares <- c("Eventos - CEBA LEE", "Eventos - RLE", "Eventos - Venezuela", "Eventos - Mariposas", "Eventos - IVIC")
eventos <- album_info %>% filter(title %in% c(lugares, eventos)) %>% pull(id)
aIDs
<- foreach(aID=aIDs, .combine = "bind_rows") %do% {
photos <- POST("https://photoslibrary.googleapis.com/v1/mediaItems:search",
dts add_headers(
'Authorization' = authorization,
'Accept' = 'application/json'),
body = list("albumId" = aID,
"pageSize" = 50),
encode = "json"
%>%
) content(., as = "text", encoding = "UTF-8") %>%
fromJSON(., flatten = TRUE) %>%
data.frame()
$album <- album_info %>% filter(id %in% aID) %>% pull(title)
dts<- dts %>%
dts mutate(
output_file = str_replace_all(mediaItems.description, "[ ,/]+", "-"),
output_id = abbreviate(mediaItems.id))
dts
}
::i_am("how2/how-to-site.qmd")
here<- here::here("lgrs","img")
img_folder if (!dir.exists(img_folder))
dir.create(img_folder)
for (i in seq(along=photos$mediaItems.id)[photos$album %in% lugares]) {
<- photos %>% slice(i)
photo <- sprintf("%s=w400-h400-d", photo$mediaItems.baseUrl)
durl <- sprintf("%s/%s-%s.jpg",img_folder, photo$output_id, photo$output_file)
dfile if (!file.exists(dfile))
download.file(url=durl, destfile=dfile)
}
<- here::here("evnts","img")
img_folder if (!dir.exists(img_folder))
dir.create(img_folder)
for (i in seq(along=photos$mediaItems.id)[photos$album %in% eventos]) {
<- photos %>% slice(i)
photo <- sprintf("%s=w400-h400-d", photo$mediaItems.baseUrl)
durl <- sprintf("%s/%s-%s.jpg",img_folder, photo$output_id, photo$output_file)
dfile if (!file.exists(dfile))
download.file(url=durl, destfile=dfile)
}
<- here::here("data","google-photos.rds")
file_name saveRDS(file=file_name, photos)
Galleries with pixture
I am experimenting with the pixture package to create image galleries.
install.packages(c("htmlwidgets","shiny","remotes"))
::install_github('royfrancis/pixture') remotes