Add JSON Feed syndication

This commit is contained in:
pancakes 2025-09-16 15:42:55 +10:00
parent fb4d9fa0aa
commit 77f3972292
Signed by: pancakes
SSH key fingerprint: SHA256:yrp4c4hhaPoPG07fb4QyQIgAdlbUdsJvUAydJEWnfTw

View file

@ -1,8 +1,11 @@
using System.Net.Mime; using System.Net.Mime;
using System.ServiceModel.Syndication; using System.ServiceModel.Syndication;
using System.Text.Json.Serialization;
using System.Xml; using System.Xml;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using PancakesWeb.Components.UI; using PancakesWeb.Components.UI;
using J = System.Text.Json.Serialization.JsonPropertyNameAttribute;
using JI = System.Text.Json.Serialization.JsonIgnoreAttribute;
namespace PancakesWeb.Controllers; namespace PancakesWeb.Controllers;
@ -45,4 +48,124 @@ public class FeedController : ControllerBase
return Content(stringWriter.ToString(), "application/atom+xml"); return Content(stringWriter.ToString(), "application/atom+xml");
} }
[HttpGet("/feed.json")]
[Produces("application/feed+json", MediaTypeNames.Application.Json)]
public JsonFeed GetJsonFeed() => new JsonFeed
{
Title = "pancakes' blog",
HomePageUrl = "https://pancakes.gay",
FeedUrl = "https://pancakes.gay/feed.json",
Description = "🐈‍⬛",
Icon = "https://pancakes.gay/icon.webp",
Favicon = "https://pancakes.gay/favicon.ico",
Authors =
[
new JsonFeedAuthor
{
Name = "pancakes",
Url = "https://pancakes.gay",
Avatar = "https://pancakes.gay/icon.webp"
}
],
Language = "en",
Items = BlogPosts.Posts.OrderByDescending(post => post.Published).Select(post => new JsonFeedItem
{
Id = $"https://pancakes.gay/{post.Slug}",
Url = $"https://pancakes.gay/{post.Slug}",
Title = post.Title,
ContentHtml = post.Content,
Summary = post.Description,
BannerImage = $"https://pancakes.gay/post-assets/{post.Slug}/{post.HeaderFilename}",
DatePublished = post.Published,
DateModified = post.Edited,
Tags = null
}).ToList()
};
public class JsonFeed
{
[J("version")] public string Version => "https://jsonfeed.org/version/1.1";
[J("title")] public required string Title { get; set; }
[J("home_page_url")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? HomePageUrl { get; set; }
[J("feed_url")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? FeedUrl { get; set; }
[J("description")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Description { get; set; }
[J("icon")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Icon { get; set; }
[J("favicon")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Favicon { get; set; }
[J("authors")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public List<JsonFeedAuthor>? Authors { get; set; }
[J("language")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Language { get; set; }
[J("items")] public List<JsonFeedItem> Items { get; set; } = [];
}
public class JsonFeedAuthor
{
[J("name")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Name { get; set; }
[J("url")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Url { get; set; }
[J("avatar")]
[JI(Condition = JsonIgnoreCondition.Never)]
public string? Avatar { get; set; }
}
public class JsonFeedItem
{
[J("id")] public required string Id { get; set; }
[J("url")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Url { get; set; }
[J("title")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Title { get; set; }
[J("content_html")] public required string ContentHtml { get; set; }
[J("summary")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Summary { get; set; }
[J("banner_image")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? BannerImage { get; set; }
[J("date_published")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public DateTime? DatePublished { get; set; }
[J("date_modified")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public DateTime? DateModified { get; set; }
[J("tags")]
[JI(Condition = JsonIgnoreCondition.WhenWritingNull)]
public List<string>? Tags { get; set; }
}
} }