feat: add JSON Feed endpoint at /api/volumen/feed.json
Implements jsonfeed.org version 1.1 with title, home_page_url, feed_url, description, language, and items with content_html and date_published.
This commit is contained in:
@@ -41,6 +41,10 @@ module Volumen
|
|||||||
feed_xml
|
feed_xml
|
||||||
end
|
end
|
||||||
|
|
||||||
|
app.get "/api/volumen/feed.json" do
|
||||||
|
json(feed_json)
|
||||||
|
end
|
||||||
|
|
||||||
app.get "/api/volumen/sitemap.xml" do
|
app.get "/api/volumen/sitemap.xml" do
|
||||||
content_type "application/xml"
|
content_type "application/xml"
|
||||||
sitemap_xml
|
sitemap_xml
|
||||||
|
|||||||
@@ -168,6 +168,41 @@ module Volumen
|
|||||||
end
|
end
|
||||||
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
|
||||||
|
}
|
||||||
|
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
|
def sitemap_xml
|
||||||
urls = published_posts.map do |post|
|
urls = published_posts.map do |post|
|
||||||
url = " <url><loc>#{escape("#{base_url}/#{post.slug}")}</loc>"
|
url = " <url><loc>#{escape("#{base_url}/#{post.slug}")}</loc>"
|
||||||
|
|||||||
@@ -141,4 +141,16 @@ class ServerTest < Minitest::Test
|
|||||||
slugs = JSON.parse(last_response.body)["posts"].map { |post| post["slug"] }
|
slugs = JSON.parse(last_response.body)["posts"].map { |post| post["slug"] }
|
||||||
refute_includes slugs, "later"
|
refute_includes slugs, "later"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_json_feed_endpoint
|
||||||
|
get "/api/volumen/feed.json"
|
||||||
|
assert_predicate last_response, :ok?
|
||||||
|
data = JSON.parse(last_response.body)
|
||||||
|
assert_equal "https://jsonfeed.org/version/1.1", data["version"]
|
||||||
|
assert_equal "My Blog", data["title"]
|
||||||
|
assert_equal 1, data["items"].length
|
||||||
|
assert_equal "Hello", data["items"].first["title"]
|
||||||
|
assert_includes data["items"].first["content_html"], "<strong>world</strong>"
|
||||||
|
refute_includes data["items"].map { |i| i["title"] }, "Draft"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user