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).
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) 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.