D.5 Paths of figures and other dependencies
One of the most challenging tasks in developing the blogdown package is to properly handle dependency files of web pages. If all pages of a website were plain text without dependencies like images or JavaScript libraries, it would be much easier for me to develop the blogdown package.
After blogdown compiles each Rmd document to HTML, it will try to detect the dependencies (if there are any) from the HTML source and copy them to the static/
folder, so that Hugo will copy them to public/
later. The detection depends on the paths of dependencies. By default, all dependencies, like R plots and libraries for HTML widgets, are generated to the foo_files/
directory if the Rmd is named foo.Rmd
. Specifically, R plots are generated to foo_files/figure-html/
and the rest of files under foo_files/
are typically from HTML widgets.
R plots under content/*/foo_files/figure-html/
are copied to static/*/foo_files/figure-html/
, and the paths in HTML tags like <img src="foo_files/figure-html/bar.png" />
are substituted with /*/foo_files/figure-html/bar.png
. Note the leading slash indicates the root directory of the published website, and the substitution works because Hugo will copy */foo_files/figure-html/
from static/
to public/
.
Any other files under foo_files/
are treated as dependency files of HTML widgets, and will be copied to static/rmarkdown-libs/
. The original paths in HTML will also be substituted accordingly, e.g., from <script src="foo_files/jquery/jquery.min.js">
to <script src="/rmarkdown-libs/jquery/jquery.min.js">
. It does not matter whether these files are generated by HTML widgets or not. The links on the published website will be correct and typically hidden from the readers of the pages.47
You should not modify the knitr chunk option fig.path
or cache.path
unless the above process is completely clear to you, and you want to handle dependencies by yourself.
In the rare cases when blogdown fails to detect and copy some of your dependencies (e.g., you used a fairly sophisticated HTML widget package that writes out files to custom paths), you have two possible choices:
Do not ignore
_files$
in the optionignoreFiles
inconfig.toml
, do not customize thepermalinks
option, and set the optionuglyURLs
totrue
. This way, blogdown will not substitute paths that it cannot recognize, and Hugo will copy these files topublic/
. The relative file locations of the*.html
file and its dependencies will remain the same when they are copied topublic/
, so all links will continue to work.If you choose to ignore
_files$
or have customized thepermalinks
option, you need to make sure blogdown can recognize the dependencies. One approach is to use the path returned by the helper functionblogdown::dep_path()
to write out additional dependency files. Basically this function returns the currentfig.path
option in knitr, which defaults to*_files/figure-html/
. For example, you can generate a plot manually underdep_path()
, and blogdown will process it automatically (copy the file and substitute the image path accordingly).
If you do not understand all these technical details, we recommend that you use the first choice, and you will have to sacrifice custom permanent links and clean URLs (e.g., /about.html
instead of /about/
). With this choice, you can also customize the fig.path
option for code chunks if you want.
For example, a reader will not see the
<script>
tag on a page, so it does not really matter what itssrc
attribute looks like as long as it is a path that actually exists.↩︎