Jekyll Inline Conditionals With Liquid Filters
Beyond The Ternary Operator
Main Content
Often times when writing Jekyll templates, we need to do some conditional matching on certain blocks of text, returning one value in one instance, and a different value in another instance. Many times only a small portion needs to be changed, such as the name of a class, or inserting a default value when a variable is nil.
Unfortunately Jekyll’s Liquid syntax does not provide inline conditionals such as the ternary operator. However, we can implement one ourselves using custom Liquid filters. In this article, I discuss several such operators that can simplify your Liquid code, and have the benefit of being easy to chain.
Ternary Operators Testing for Existence
Take a block from a Jekyll template like so:
There’s quite a bit of duplication here already, and if the header
block
included more variable attributes (such as a class name) things could get quickly
out of hand.
I have many blocks like this in the theme I created for this site. In order to make things easier to read (and thus, easier for future me to maintain), I wrote a simple Jekyll filter.
Using this filter I can simplify the template code to
For readers unfamiliar with ternary operators, what this is doing is testing if
page.feature
exits and, if it is, returns page.feature.image
; otherwise, it
returns site.feature.image
.
This is still a bit wordy in some cases; for example, if the tested value is the same as the first return value, we would duplicate that slice of code. Read ahead for an even DRYer solution.
Providing Defaults for Blank Values
We can add a second filter to this plugin module. Note that here we are testing
explicity if the value passed to the filter is nil
, which with Jekyll is true
both when the YAML front-matter is missing or when the tag is present but left
blank. When the value is missing, we return the default, otherwise we return the
value itself.
Using this filter we can rewrite this template snippet as
Now this is a nice, DRY way to write Jekyll.
Ternary Operator Matching on Values
The previous two scenarious dealt with missing values, but there are cases where we want to test equality instead, returning two different values. In my Jekyll theme this comes up often in the navigation bar, when determining the active tab. Without any custom filters, a single link in the navbar would look like
This block of code is repeated for each static page, along with once in a for
loop for the category pages. Not only is this excessively wordy, it separates
the opening and closing li
tags in a way that could be confusing in a larger
template.
We can repeate the pattern for the previous filters, this time taking three
arguments: a matcher
to match against, and the true_value
and false_value
to return depending on wheter the inpug value
matches the matcher
.
With this filter, we can easily have a list of links with only the appropriate one marked as active
If I wanted to, I could created an even more specialized form of this filter
named something like active_if
, and return active
or inactive
directly.
Final Module and Conclusion
Combining all of these along with a reverse of the first if
filter (called,
appropriately enough, unless
), the final plugin is below.
I’ve found it much easier to develop complex Jekyll templates with the conditional logic inline, particularly as control structures get nested. I’ll be releasing full code of my theme in the coming days, so stay tuned.