I use the postfiles plugin by André Arko to add static files to the posts that I write. It is a great addition, because it allows to group the static files together with the post in a sensible way (although I still find myself searching for the correct folder name, and have added a rake task to make it easier to find, may blog on it later). However, I noticed a few issues in my blog, that has category names that include spaces. I assume that the same error occurs in other special characters, that get
CGI.escaped during processing by Jekyll.
The Cause (1/2)
In the Jekyll source, each of the file types (Post, Page and StaticFile) have a
write method, that in turn calls
destination to calculate the correct file/folder name. I guess it is by design that the
StaticFile version uses the filenames verbatim, while
Page do some unescaping. I assume this was done because a static file typically has no Category, so will simply get its place in the filesystem under
_site without needing processing. In the
postfiles case, though, we are working with
CGI.encoded folder names because they were generated from the processing of the matching post.
The lack of unescaping causes a
StaticFile that contains a special character in its category to have a path that contains a percent sign. For example, the category
Computer stuff will end up in the folder
_site/Computer stuff, but the
post.url will contain the string
Computer%20stuff. This ends up being a folder that the server cannot find, because it is uncoding the
%20 again, to a space.
The Cause (2/2)
In the jekyll-postfiles plugin, there is a regexp that splits out the parts of the post id, to form the folder name where it searches for the postfiles. This regexp uses
[\s\w\/]* to parse away the leading path details. This chokes on the
CGI.encoded paths, because the word characters
\w do not match the percent sign
%. This leads to the leading part of the path not matching the regexp, thus generating incorrect paths.
Easy. Add percent to the pathname regexp:
CGI.decode the directory portion of the filename before passing it back to Jekyll:
The diff of my edits can be found here on GitHub.
Making it permanent
I have created a pull request against the jekyll-postfiles plugin, which can be found here. It was subsequently accepted by the owner, so is now a permanent part of the repo.