diff --git a/Gemfile b/Gemfile index b6621ae..f4b9035 100644 --- a/Gemfile +++ b/Gemfile @@ -4,6 +4,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } gem "activesupport" gem "bridgetown", "~> 0.19.1" gem "dotenv" +gem "icalendar", "~> 2.7", require: false gem "rake" group :bridgetown_plugins do diff --git a/Gemfile.lock b/Gemfile.lock index 4efc4bc..d31ab02 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - activesupport (6.1.0) + activesupport (6.1.3.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -9,15 +9,15 @@ GEM zeitwerk (~> 2.3) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) - amazing_print (1.2.2) + amazing_print (1.3.0) ast (2.4.2) - bridgetown (0.19.1) - bridgetown-builder (= 0.19.1) - bridgetown-core (= 0.19.1) - bridgetown-paginate (= 0.19.1) - bridgetown-builder (0.19.1) - bridgetown-core (= 0.19.1) - bridgetown-core (0.19.1) + bridgetown (0.19.3) + bridgetown-builder (= 0.19.3) + bridgetown-core (= 0.19.3) + bridgetown-paginate (= 0.19.3) + bridgetown-builder (0.19.3) + bridgetown-core (= 0.19.3) + bridgetown-core (0.19.3) activesupport (~> 6.0) addressable (~> 2.4) amazing_print (~> 1.2) @@ -29,55 +29,60 @@ GEM i18n (~> 1.0) kramdown (~> 2.1) kramdown-parser-gfm (~> 1.0) - liquid (~> 4.0) + liquid (~> 5.0) liquid-component (>= 0.1) - liquid-render-tag (~> 0.2) listen (~> 3.0) pathutil (~> 0.9) rouge (~> 3.0) safe_yaml (~> 1.0) terminal-table (~> 1.8) - thor (~> 1.0) + thor (~> 1.1) tilt (~> 2.0) webrick (~> 1.7) bridgetown-minify-html (1.0.1) bridgetown (>= 0.15, < 2.0) htmlcompressor (>= 0.4, < 1.0) - bridgetown-paginate (0.19.1) - bridgetown-core (= 0.19.1) + bridgetown-paginate (0.19.3) + bridgetown-core (= 0.19.3) bridgetown-seo-tag (3.0.5) bridgetown (>= 0.15.0, < 2.0) colorator (1.1.0) - concurrent-ruby (1.1.7) + concurrent-ruby (1.1.8) dotenv (2.7.6) erubi (1.10.0) - faraday (1.3.0) + faraday (1.4.1) + faraday-excon (~> 1.1) faraday-net_http (~> 1.0) + faraday-net_http_persistent (~> 1.1) multipart-post (>= 1.2, < 3) - ruby2_keywords - faraday-net_http (1.0.0) + ruby2_keywords (>= 0.0.4) + faraday-excon (1.1.0) + faraday-net_http (1.0.1) + faraday-net_http_persistent (1.1.0) faraday_middleware (1.0.0) faraday (~> 1.0) - ffi (1.14.2) + ffi (1.15.0) forwardable-extended (2.6.0) hash_with_dot_access (1.1.0) activesupport (>= 5.0.0, < 7.0) htmlcompressor (0.4.0) - i18n (1.8.7) + i18n (1.8.10) concurrent-ruby (~> 1.0) - kramdown (2.3.0) + icalendar (2.7.1) + ice_cube (~> 0.16) + ice_cube (0.16.3) + kramdown (2.3.1) rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) - liquid (4.0.3) + liquid (5.0.1) liquid-component (0.1.0) activesupport (>= 5.0) safe_yaml (~> 1.0) - liquid-render-tag (0.2.0) - listen (3.4.0) + listen (3.5.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - minitest (5.14.2) + minitest (5.14.4) multipart-post (2.1.1) parallel (1.20.1) parser (3.0.1.0) @@ -91,7 +96,7 @@ GEM rb-inotify (0.10.1) ffi (~> 1.0) regexp_parser (2.1.1) - rexml (3.2.4) + rexml (3.2.5) rouge (3.26.0) rubocop (1.12.1) parallel (~> 1.10) @@ -108,7 +113,7 @@ GEM rubocop (>= 0.90.0, < 2.0) rubocop-ast (>= 0.4.0) ruby-progressbar (1.11.0) - ruby2_keywords (0.0.2) + ruby2_keywords (0.0.4) safe_yaml (1.0.5) standard (1.0.5) rubocop (= 1.12.1) @@ -117,7 +122,7 @@ GEM standard terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) - thor (1.0.1) + thor (1.1.0) tilt (2.0.10) tzinfo (2.0.4) concurrent-ruby (~> 1.0) @@ -134,6 +139,7 @@ DEPENDENCIES bridgetown-minify-html bridgetown-seo-tag dotenv + icalendar (~> 2.7) rake standardrb diff --git a/netlify.toml b/netlify.toml index b6a38a7..b6bc0d0 100644 --- a/netlify.toml +++ b/netlify.toml @@ -35,3 +35,7 @@ for = "/*.(png|jpg|js|css|svg|woff|ttf|eot|ico)" [headers.values] Cache-Control = "public, max-age=31536000, s-max-age=31536000" +[[headers]] + for = "/*.(ical)" + [headers.values] + Content-Type = "text/calendar" diff --git a/plugins/builders/ical_builder.rb b/plugins/builders/ical_builder.rb new file mode 100644 index 0000000..ae2133c --- /dev/null +++ b/plugins/builders/ical_builder.rb @@ -0,0 +1,56 @@ +require "icalendar" + +class IcalBuilder < SiteBuilder + def build + hook :site, :post_write do + generate(site) + end + end + + private + + # Main plugin action, called by Bridgetown-core + def generate(site) + @site = site + return if file_exists?(file_path) + make_ical_file + end + + def make_ical_file + File.write(file_path, ical_output) + end + + def file_path + File.join(site.dest, "ical.ical") + end + + # Checks if a file already exists in the site source + def file_exists?(file_path) + File.exist? @site.in_source_dir(file_path) + end + + def ical_output + cal = Icalendar::Calendar.new + cal.prodid = "-//Ruby Meetup Calendar//Calendar 1.0//EN" + cal.append_custom_property("X-WR-CALNAME", "Ruby Meetup Calendar") + cal.append_custom_property("X-WR-TIMEZONE", "Etc/UTC") + cal.append_custom_property("X-PUBLISHED-TTL", "PT24H") + cal.append_custom_property("X-WR-CALDESC", "Find Ruby Meetup Events") + + @site.collections.events.docs.each do |event| + ical_event = Icalendar::Event.new + ical_event.uid = event.url + ical_event.dtstart = Icalendar::Values::DateTime.new(event[:datetime].to_datetime.utc, tzid: "UTC") + ical_event.summary = event[:title] + ical_event.description = event[:external_url] + ical_event.url = event[:external_url] + ical_event.status = "CONFIRMED" + ical_event.transp = "OPAQUE" + ical_event.sequence = 0 + cal.add_event(ical_event) + end + + cal.publish + cal.to_ical + end +end diff --git a/src/_partials/_calendar.erb b/src/_partials/_calendar.erb index e2b6d8b..829df72 100644 --- a/src/_partials/_calendar.erb +++ b/src/_partials/_calendar.erb @@ -23,7 +23,7 @@ <%= partial 'calendar/nav_button', month: current_month + 1.months, forward_svg: true %> - +