As you may have no­ticed, I added table of con­tents to ap­pro­pri­ate posts. If you had­n’t no­ticed, take a look at the re­lease notes from the lat­est ver­sion.

Having a table of con­tents on longer posts is awe­some. Some of the longer re­views and de­vel­op­ment ar­ti­cles are much eas­ier to con­sume by know­ing what’s in the ar­ti­cle. Adding a table of con­tents to a Jekyll post is a piece of cake with Kramdown:

* table of contents
{:toc}

All was fine and dandy with the new table of con­tents till I re­al­ized that they were be­ing out­put in the RSS feed. 🤦🏽‍ I did­n’t want that! After search­ing the vast in­ter­net cos­mos for more than an hour, I was­n’t find­ing what I needed. Shocked and dis­ap­pointed think­ing that no one had writ­ten about this, I al­most gave up.

Then, fi­nally, I found it. Well… not re­ally. The ar­ti­cle is about re­mov­ing foot­notes from ex­cerpts in Jekyll with the help of the noko­giri gem. This was­n’t what I was try­ing to do, but close enough that I could mod­ify and make it work.

The Solution #

Create a Jekyll Plugin #

Go to your _plugins folder and cre­ate a new Ruby file. You can call it what­ever you’d like, I called mine stripTOC.rb

# stripTOC.rb

require 'nokogiri'

module Jekyll
module StripTocFilter

def strip_toc(raw)
doc = Nokogiri::HTML.fragment(raw.encode('UTF-8', :invalid => :replace, :undef => :replace, :replace => ''))

for block in ['ul'] do
doc.css(block).each do |ele|
ele.remove if (ele['id'] == 'markdown-toc')
end
end

doc.inner_html

end
end
end

Liquid::Template.register_filter(Jekyll::StripTocFilter)

This code cre­ates a new fil­ter that we can use to re­move the table of con­tents from our RSS feed. If you no­ticed, we’re telling it to find any el­e­ment with the #markdown-toc id. This is the id as­signed to it by Kramdown.

A Note About Plugins on GitHub Pages

The fol­low­ing method will only work if you self-host your Jekyll site. GitHub Pages does­n’t al­low cus­tom plu­g­ins.

Filtering Our RSS Feed #

Now we want to open up our feed and use the fil­ter. Mine is called atom.xml.

<!-- atom.xml -->
<content type="html">
<![CDATA[
{{ post.content | strip_toc }}
]]>

</content>

Now your table of con­tents is pre­sent on your ar­ti­cles, but does­n’t clut­ter up the RSS feed.

Series Hacking Jekyll

As I learn things about Jekyll, I try to write about them.

View Series →

Up Next