Jekyll stealth mode

Lets Jekylling!

Permalink to heading Why “Jekyll”? Why “Jekyll”?

First, read original blog post from Tom Preston-Werner. Then, the philosophy is excellent:

Jekyll does what you tell it to do — no more, no less. It doesn’t try to outsmart users by making bold assumptions, nor does it burden them with needless complexity and configuration. Put simply, Jekyll gets out of your way and allows you to concentrate on what truly matters: your content.

It does what it says, nothing more, no unnecessary complexity. Nothing is perfect, but Jekyll is light and fun. I appreciate that. Besides, code and documentation are strikingly readable.

We’ll see some cool features in the next sections \o/.

Permalink to heading Where does the name come from? Where does the name come from?

If you are interested in this topic, let’s talk about the name, if not, you can skip this non-technical section.

You know, naming things is hard. I always pay attention to that, whether or not it has some meaning.

I’m not sure about the details, but, IMHO, it obviously comes from the novel The Strange Case of Dr. Jekyll and Mr. Hyde, and the dual nature of Henry/Edward Hyde.

Jekyll transforms source files in markdown into static HTML files. That would make two folders for two different natures. Nevertheless, I don’t see “good” and “evil”… at the end of the day, it’s a tool. Maybe it’s just an allusion.

Permalink to heading Using live reload Using live reload

Don’t use plugins for that, there is a --livereload option:

bundle exec jekyll serve --livereload

You can alternatively use the shortcut -l or even set livereload to true in your _config.yml.

Permalink to heading Set up multiple environments Set up multiple environments

If you need different settings depending on the environment (local, staging, production), you can use your _config.yml for global settings across environments and override things in specific files:


This prevents unnecessary duplication, then run:

bundle exec jekyll serve --config _config.yml,_config_development.yml


Besides, the global environment variable JEKYLL_ENV allows for specific usages in code:

{% if jekyll.environment == "prod" %}
    {% include tracking.html %}
{% endif %}

but don’t forget to use it in your command:

JEKYLL_ENV=prod jekyll build

By default, JEKYLL_ENV equals “development.”

Permalink to heading Skipping files and directories Skipping files and directories

If you don’t use any YAML front matter, Jekyll does not apply any transformation to your file:


So no Liquid parsing, etc. But, if you do not want your files or your directory to be copied in the destination folder, use an underscore or a tilde as name prefix:


Alternatively, you can use the exclude settings in your _config.yml:

exclude: ["mydir", "myfile.txt"]

Permalink to heading How to disable Liquid How to disable Liquid

Just add render_with_liquid: false to the YAML front matter of your source file, and Liquid processing is disabled.

Simple as that.

Permalink to heading How to create plugins How to create plugins

Any .rb file in _plugins is a custom plugin. Jekyll is pluggable. For example, you can add a custom converter if your source files are neither markdown nor textile.

Hooks are great too. You can use these event handlers to perform actions.

The documentation provides the following skeleton:

Jekyll::Hooks.register :posts, :post_render do |post|
    # code \o/

First, clean your installation:

bndle exec jekyll clean

Then I recommend the --trace and the --verbose options:

bundle exec jekyll serve --trace --verbose

To filter content object, you can use the following:

Jekyll::Hooks.register([:posts], :pre_render) do |doc|
    doc.content = doc.content.sub('\o/','╰(▔∀▔)╯')

N.B: it’s a quick and dirty example, please be extra cautious with those replacements.

The first argument is the container, the second argument is the event. If you need to target all collections use :documents instead of :posts as first argument.

Anyway, it’s totally possible to filter post content on the fly before rendering.

If you are looking for some good practices regarding hooks, you can read the code of jemoji.

There are some coding standards.

Permalink to heading What are unless and contains? What are unless and contains?

Liquid is nice. Contains is pretty self-explanatory:

{% if myvar contains "" %}
    # code \o/
{% endif %}

Unless is a “reverse if”. Unless + contains equals “does not contain”:

{% unless myvar contains "" %}
    it's not Shopify
{% endunless %}

Some developers assert it’s not a programmer-friendly language. Well, Ruby is, for sure, but I don’t have any problem with Liquid, it’s fun and quite robust. If you have issues, please share.

Permalink to heading Working with themes Working with themes

Most of the themes are gem-based themes. In other words, it’s like any other gem you can add to your Gemfile. By default, Jekyll uses the “minima” theme:

gem "minima", "~> 2.5"

Indeed, you can remove this line or add another gem-based theme. You can also override specific parts of a theme in your main site folders. Jekyll looks first in the gem-based theme then on your site.

If you are a theme developer, please follow the guidelines.

Permalink to heading Wrap up Wrap up

I hope you enjoy those thoughts and tricks about Jekyll. Happy Jekylling!

I do my best to update all my contents, but keep it mind that "Jekyll stealth mode" has been published many months ago.