Notes on Jekyll
Published on
Here I describe a couple of Jekyll issues that I had to debug recently.
Broken symlinks
I have many relative symlinks in my jekyll directory that point
outside of it. For instance, docs/2010-10-22-posix.pdf is a
symlink to ../../kpi/POSIX/2010-10-22-posix.pdf
.
Recently I noticed that these symlinks are broken in jekyll’s
generated directory, _site
. It appears that jekyll copies
the link as is, that is as a relative link to
../../kpi/POSIX/2010-10-22-posix.pdf
, but because the
location of the link changed from $JEKYLL_ROOT
to
$JEKYLL_ROOT/_site
, it no longer pointed into the right
place.
So I dug into the source code and found this in
lib/jekyll/static_file.rb
:
def copy_file(dest_path)
if @site.safe || Jekyll.env == "production"
FileUtils.cp(path, dest_path)
else
FileUtils.copy_entry(path, dest_path)
end
unless File.symlink?(dest_path)
File.utime(self.class.mtimes[path], self.class.mtimes[path], dest_path)
end
end
As described in the docs
for FileUtils, cp
copies the file content, similarly to
cp -L
, while copy_entry
copies a link as a
link, like cp -d
.
As the code implies, the behavior we want (FileUtils.cp
)
can be triggered by setting the environment to
production
:
JEKYLL_ENV=production
I don’t see why this shouldn’t be the default behavior, so I opened an issue.
Interestingly, I’m pretty sure it used to work properly before. When
I discovered the issue, I rushed to check whether my site has been
broken all this time, but the files were in the right places on the
server. I thought that maybe this is a recent regression, but
git blame
says that this piece of code hasn’t changed in
years. I still have not solved this mystery.
A case of a missing file
I needed to publish the files of a research project I’m working on.
The main code for the project is in an R markdown notebook (“Rmd”). I
was going to publish the raw code.Rmd
file, so that others
could run it, as well as its rendered version,
code.html
.
When I looked into the _site
directory,
code.html
was there, but code.Rmd
was
mysteriously missing.
It took me a while to find the problem, but it is a simple one: Rmd
is a markdown file with a YAML front matter — just like the markdown
files jekyll has to process. So the code.html
I was seeing
was not the original code.html
(which contains the output
of the R code) but the Rmd file rendered by jekyll. And like all the
other jekyll’s input files, code.Rmd
was not copied into
the output directory.
This problem was discussed before (here and here),
and the advice was to make jekyll ignore the problematic
files/directories and then use something else (like Gulp) to copy them
into the _site
directory.
This seemed too complicated to me, so I made a small patch to support “verbatim” directories, which are copied as is even if some of the files contain the YAML front matter. To enable this, simply add
verbatim:
- files
to your _config.yml
, where files
is the
name of the directory to copy verbatim.
I submitted this feature as a pull request, which I hope will be accepted, but for the time being you can get it from my fork of the jekyll repo.