I have searched tirelessly for this on Google but unfortunately every search collides with the fact Jekyll is a site generator and the results do not help.
I'm looking for a small example of how to read an ICS file from a plugin/generator that is then accessible with liquid from the templates.
I've tried creating collections and appending to them in plugins, I've tried creating site.data
arrays. Nothing seems to work. Is there a small example of a jekyll plugin that reads a file or url and creates data that is then stored in a site variable and can be accessed via liquid? Specifically I'll be reading an ICS feed and creating a calendar.
Data files might not be able to fulfil your requirement. You need a Jekyll Plugin.
Here's an ad-hoc solution I would implement to read ics
files and expose calendar events to liquid variables in Jekyll:
Add icalendar
to your Gemfile
and install it:
bundle add icalendar
bundle install
Put this file in _plugins/calendar_reader.rb
require "jekyll"
require "icalendar"
module Jekyll
module ICSReader
def read_calendar(input)
begin
calendar_file = File.open(input)
events = Icalendar::Event.parse(calendar_file)
hash = {}
counter = 0
# loop through the events in the calendars
# and map the values you want into a variable and then return it:
events.each do |event|
hash[counter] = {
"summary" => event.summary,
"dtstart" => event.dtstart,
"dtend" => event.dtend,
"description" => event.description
}
counter += 1
end
return hash
rescue
# Handle errors
Jekyll.logger.error "Calendar Reader:", "An error occurred!"
return {}
end
end
end
end
Liquid::Template.register_filter(Jekyll::ICSReader)
The README.md
docs of icalendar
would help you understand how data is being read from the file. Basically, we parse the events in the file and map them to a dictionary and return it.
Now take an ics file and put it into the _data
folder.
_data/my_calendar.ics
BEGIN:VEVENT
DTSTAMP:20050118T211523Z
UID:bsuidfortestabc123
DTSTART;TZID=US-Mountain:20050120T170000
DTEND;TZID=US-Mountain:20050120T184500
CLASS:PRIVATE
GEO:37.386013;-122.0829322
ORGANIZER:mailto:joebob@random.net
PRIORITY:2
SUMMARY:This is a really long summary to test the method of unfolding lines
\, so I'm just going to make it a whole bunch of lines.
ATTACH:http://bush.sucks.org/impeach/him.rhtml
ATTACH:http://corporations-dominate.existence.net/why.rhtml
RDATE;TZID=US-Mountain:20050121T170000,20050122T170000
X-TEST-COMPONENT;QTEST="Hello, World":Shouldn't double double quotes
END:VEVENT
BEGIN:VEVENT
DTSTAMP:20110118T211523Z
UID:uid-1234-uid-4321
DTSTART;TZID=US-Mountain:20110120T170000
DTEND;TZID=US-Mountain:20110120T184500
CLASS:PRIVATE
GEO:37.386013;-122.0829322
ORGANIZER:mailto:jmera@jmera.human
PRIORITY:2
SUMMARY:This is a very short summary.
RDATE;TZID=US-Mountain:20110121T170000,20110122T170000
END:VEVENT
This sample ics file is taken from the icalendar repository.
Now you can use the plugin filter from your markdown/html:
{% assign events = "_data/my_calendar.ics" | read_calendar %}
Here read_calendar
is the function defined in _plugins/calendar_reader.rb
and _data/my_calendar.ics
is the file you want to get the data from. The plugin gets the input
as _data/my_calendar.ics
, reads it and returns a hash
which is stored into the events
variable itself.
You can now use {{ events }}
to access the hash of the data that you return from the function in the plugin file.
// {{ events }}
{0=>{“summary”=>”This is a really long summary to test the method of unfolding lines, so I’m just going to make it a whole bunch of lines.”, “dtstart”=>#<DateTime: 2005-01-20T17:00:00+00:00 ((2453391j,61200s,0n),+0s,2299161j)>, “dtend”=>#<DateTime: 2005-01-20T18:45:00+00:00 ((2453391j,67500s,0n),+0s,2299161j)>, “description”=>nil}, 1=>{“summary”=>”This is a very short summary.”, “dtstart”=>#<DateTime: 2011-01-20T17:00:00+00:00 ((2455582j,61200s,0n),+0s,2299161j)>, “dtend”=>#<DateTime: 2011-01-20T18:45:00+00:00 ((2455582j,67500s,0n),+0s,2299161j)>, “description”=>nil}}
// {{ events[0] }}
{“summary”=>”This is a really long summary to test the method of unfolding lines, so I’m just going to make it a whole bunch of lines.”, “dtstart”=>#<DateTime: 2005-01-20T17:00:00+00:00 ((2453391j,61200s,0n),+0s,2299161j)>, “dtend”=>#<DateTime: 2005-01-20T18:45:00+00:00 ((2453391j,67500s,0n),+0s,2299161j)>, “description”=>nil}
// {{ events[1] }}
{“summary”=>”This is a very short summary.”, “dtstart”=>#<DateTime: 2011-01-20T17:00:00+00:00 ((2455582j,61200s,0n),+0s,2299161j)>, “dtend”=>#<DateTime: 2011-01-20T18:45:00+00:00 ((2455582j,67500s,0n),+0s,2299161j)>, “description”=>nil}
This was the bare-bones of how a Jekyll Filter
works. You can dive deeper into other types of Jekyll Plugins as explained in the docs.