diff --git a/lib/volumen/feed_helpers.rb b/lib/volumen/feed_helpers.rb
new file mode 100644
index 0000000..60e94b2
--- /dev/null
+++ b/lib/volumen/feed_helpers.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+module Volumen
+ # RSS, JSON Feed, and sitemap helpers extracted from Server to keep the
+ # main class focused on configuration and routing.
+ module FeedHelpers
+ private
+
+ def feed_xml
+ site = config.site
+ items = published_posts.first(20).map { |post| feed_item(post) }.join("\n")
+ <<~XML
+
+
+
+ #{escape(site["title"])}
+ #{escape(base_url)}
+ #{escape(site["description"])}
+ #{escape(site["language"])}
+ #{items}
+
+
+ XML
+ end
+
+ def feed_item(post)
+ link = "#{base_url}/#{post.slug}"
+ pub = if post.metadata["date"]
+ "\n #{escape(rfc822_date(post))}"
+ else
+ ""
+ end
+ creator = post.fediverse_creator
+ creator_tag = creator ? "\n #{escape(creator)}" : ""
+ <<~XML.chomp
+ -
+ #{escape(post.title)}
+ #{escape(link)}
+ #{escape(link)}
+ #{escape(post.excerpt)}#{pub}#{creator_tag}
+
+ XML
+ end
+
+ def rfc822_date(post)
+ value = post.metadata["date"]
+ case value
+ when Date then value.to_time.rfc822
+ when Time then value.rfc822
+ end
+ end
+
+ def feed_json
+ site = config.site
+ feed_url = "#{base_url}/api/volumen/feed.json"
+ {
+ "version" => "https://jsonfeed.org/version/1.1",
+ "title" => site["title"],
+ "home_page_url" => base_url,
+ "feed_url" => feed_url,
+ "description" => site["description"],
+ "language" => site["language"],
+ "items" => published_posts.first(20).map { |post| json_feed_item(post) }
+ }
+ end
+
+ def json_feed_item(post)
+ link = "#{base_url}/#{post.slug}"
+ item = {
+ "id" => link,
+ "url" => link,
+ "title" => post.title,
+ "content_html" => post.html,
+ "summary" => post.excerpt,
+ "date_published" => iso_date(post.metadata["date"]),
+ "tags" => post.tags
+ }
+ author = post.fediverse_creator || site_fediverse_creator
+ item["authors"] = [{ "name" => author }] if author
+ item.reject { |_k, v| v.nil? || v == "" || v == [] }
+ end
+
+ def iso_date(value)
+ case value
+ when Date then value.iso8601
+ when Time then value.to_date.iso8601
+ end
+ end
+
+ def sitemap_xml
+ urls = published_posts.map do |post|
+ url = " #{escape("#{base_url}/#{post.slug}")}"
+ url << "#{escape(post.date_string)}" if post.date_string
+ url << ""
+ end.join("\n")
+ <<~XML
+
+
+ #{urls}
+
+ XML
+ end
+ end
+end
diff --git a/lib/volumen/server.rb b/lib/volumen/server.rb
index dc83dc7..b55779f 100644
--- a/lib/volumen/server.rb
+++ b/lib/volumen/server.rb
@@ -10,6 +10,7 @@ require_relative "markdown"
require_relative "password"
require_relative "api_routes"
require_relative "admin_routes"
+require_relative "feed_helpers"
module Volumen
# Sinatra application: the public JSON API at /api/volumen and the
@@ -25,6 +26,7 @@ module Volumen
register ApiRoutes
register AdminRoutes
+ helpers FeedHelpers
configure do
set :show_exceptions, false
@@ -167,101 +169,6 @@ module Volumen
config.site["base_url"].to_s.chomp("/")
end
- def feed_xml
- site = config.site
- items = published_posts.first(20).map { |post| feed_item(post) }.join("\n")
- <<~XML
-
-
-
- #{escape(site["title"])}
- #{escape(base_url)}
- #{escape(site["description"])}
- #{escape(site["language"])}
- #{items}
-
-
- XML
- end
-
- def feed_item(post)
- link = "#{base_url}/#{post.slug}"
- pub = if post.metadata["date"]
- "\n #{escape(rfc822_date(post))}"
- else
- ""
- end
- creator = post.fediverse_creator
- creator_tag = creator ? "\n #{escape(creator)}" : ""
- <<~XML.chomp
- -
- #{escape(post.title)}
- #{escape(link)}
- #{escape(link)}
- #{escape(post.excerpt)}#{pub}#{creator_tag}
-
- XML
- end
-
- def rfc822_date(post)
- value = post.metadata["date"]
- case value
- when Date then value.to_time.rfc822
- when Time then value.rfc822
- end
- end
-
- def feed_json
- site = config.site
- feed_url = "#{base_url}/api/volumen/feed.json"
- {
- "version" => "https://jsonfeed.org/version/1.1",
- "title" => site["title"],
- "home_page_url" => base_url,
- "feed_url" => feed_url,
- "description" => site["description"],
- "language" => site["language"],
- "items" => published_posts.first(20).map { |post| json_feed_item(post) }
- }
- end
-
- def json_feed_item(post)
- link = "#{base_url}/#{post.slug}"
- item = {
- "id" => link,
- "url" => link,
- "title" => post.title,
- "content_html" => post.html,
- "summary" => post.excerpt,
- "date_published" => iso_date(post.metadata["date"]),
- "tags" => post.tags
- }
- author = post.fediverse_creator || site_fediverse_creator
- item["authors"] = [{ "name" => author }] if author
- item.reject { |_k, v| v.nil? || v == "" || v == [] }
- end
-
- def iso_date(value)
- case value
- when Date then value.iso8601
- when Time then value.to_date.iso8601
- end
- end
-
- def sitemap_xml
- urls = published_posts.map do |post|
- url = " #{escape("#{base_url}/#{post.slug}")}"
- url << "#{escape(post.date_string)}" if post.date_string
- url << ""
- end.join("\n")
- <<~XML
-
-
- #{urls}
-
- XML
- end
-
def escape(text)
Rack::Utils.escape_html(text.to_s)
end