These days, when there is a need to create a simple static site I turn to Jekyll. But, while Jekyll is great at what it does I often want to bend it to do something beyond what it can easily do out of the box. Rather than fork Jekyll for my small changes I use Aspect-Oriented Programming (AOP) in a way that may look familiar to anyone who has used event systems or the Drupal hook system. Here’s how I do it.
Note: Before we get started I need to point out that the techniques I’m about to describe do not work on Github pages (which support Jekyll).
The Setup
Jekyll_ext is an extension to Jekyll that enables AOP. This needs to be installed alongside Jekyll for this to work. Then, instead of calling jekyll
at the command line call ejekyll
. The same command line options apply as ejekyll
is a wrapper around jekyll
while enabling AOP.
What You Get With Jekyll_ext
There are three new ways to extent Jekyll with this extension:
- AOP.before - this allows a function to run before a method on a class does.
- AOP.after - this is like API.before but allows a function to be run after a method on a class.
- APO.around - this wraps a method call in a function. The original method needs to be manually called when it’s needed.
More details can be found on the original blog post announcing jekyll_ext and in the source code.
A Simple Example
My original use case that brought me to this method of extending Jekyll was the need for post previews that were the first part of the post before a separator (html comment). While this was a carry over from a Drupal migration it was something I found useful. Here is code that accomplishes this:
module Jekyll
class Post
def preview_content
delimeter = @site.config['content_delimeter'] || '<!-- -**-END-**- -->'
self.content.split(delimeter)[0]
end
end
AOP.around(Post, :to_liquid) do |post_instance, args, proceed, abort|
result = proceed.call
result['preview'] = post_instance.preview_content
result
end
end
The first part of this adds the method preview_post
to the class Post
. The second part wraps the method call to_liquid
on the class Post
with this function. Inside it starts by calling the original method then adds the variable (which will be accessible in the template) preview.
If you are looking for more examples a good place to start is the author of jekyll_ext repo of extensions.