Last active
January 27, 2022 19:10
-
-
Save burchill/8392b2a753652e24a35a8a1dd707c1b1 to your computer and use it in GitHub Desktop.
Make htmlwidgets work with knitr-powered Jekyll and GitHub Pages
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#' Set knitr hooks for htmlwidgets with Jekyll/GitHub Pages | |
#' | |
#' This functions sets a `knitr` hook so that any HTML widgets that were | |
#' printed (i.e., objects that inherit the `'htmlwidget'`, like those from | |
#' the `htmlwidgets` or `plotly` packages) will work with a Jekyll system, | |
#' like the one used for GitHub Pages. | |
#' | |
#' It essentially sets a hook so that, when the document is finished being | |
#' knitted, it moves all the dependencies necessary for the widgets to a | |
#' directory, and then adds HTML code to the document to load those files | |
#' from their new location. Additionally, it sets the default | |
#' `screenshot.force` chunk option to `FALSE`, so `knitr` doesn't try to | |
#' use a screenshot instead of the widget. | |
#' | |
#' See https://www.zachburchill.ml/plotly_with_jekyll/ for background | |
#' and (https://gist.github.com/burchill/9df0f6245ea7768e5b6bbd0a1c22db08) | |
#' for the old, bad version of this script. | |
#' | |
#' @param dep_dir The directory you want to save the dependencies to. | |
#' @param base_path The directory you want to make the dependency links relative to. | |
#' For example, if your post is at the url `yoursite.com/this_post/`, then you'll | |
#' want to make `base_path` the home directory of your project. | |
#' @param hrefFilter This function lets you perform any additional manipulations | |
#' to the dependency links. For some reason, when I give my base directory as my | |
#' project's home directory, the links come back without the necessary "/" in front | |
#' of them. This function adds that to each link. | |
#' @export | |
set_widget_hooks <- function(dep_dir, base_path, | |
hrefFilter = function(x) paste0("/", x)) { | |
# Move the dependencies into the specified folder, | |
# makes them relative to the base directory, | |
# and outputs the HTML that loads them. | |
render_deps <- function() { | |
l <- knitr::knit_meta(class = "html_dependency", | |
clean = FALSE) | |
if (length(l) > 0) | |
dir.create(dep_dir, showWarnings = FALSE, recursive = TRUE) | |
l <- lapply(unique(l), function(dep) { | |
dep <- htmltools::copyDependencyToDir(dep, dep_dir, FALSE) | |
dep <- htmltools::makeDependencyRelative(dep, base_path, FALSE) | |
dep } ) | |
l <- htmltools::renderDependencies(l, hrefFilter=hrefFilter) | |
htmltools::htmlPreserve(l) | |
} | |
# Adds the dependency-loading HTML at the end of the doc, | |
# without upsetting the previous doc-hook. | |
prev_doc_hook <- knitr::knit_hooks$get("document") | |
knitr::knit_hooks$set(document = function(x) { | |
prev_doc_hook(append(x, render_deps())) | |
}) | |
# Sets the default of all chunks to not force | |
# screenshots. You can change it to `TRUE` | |
# on the chunks you want it to screenshot. | |
knitr::opts_chunk$set(screenshot.force=FALSE) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment