diff --git a/Backend/Utils.cs b/Backend/Utils.cs
index e1beea2..c81fc2b 100644
--- a/Backend/Utils.cs
+++ b/Backend/Utils.cs
@@ -1,4 +1,7 @@
using System.Reflection;
+using System.ServiceModel.Syndication;
+using System.Text;
+using System.Xml;
namespace zotanpw.Backend;
@@ -21,4 +24,18 @@ public static class Utils {
_ => "a"
};
}
-}
\ No newline at end of file
+
+ public static string ToXmlString(this SyndicationFeedFormatter feed) {
+ using var sw = new StringWriterWithEncoding(Encoding.UTF8);
+ using (var xw = XmlWriter.Create(sw, new XmlWriterSettings { Encoding = Encoding.UTF8 }))
+ feed.WriteTo(xw);
+
+ return sw.ToString();
+ }
+
+ private sealed class StringWriterWithEncoding : StringWriter {
+ public StringWriterWithEncoding(Encoding encoding) => Encoding = encoding;
+
+ public override Encoding Encoding { get; }
+ }
+}
diff --git a/Controllers/AtomFeed.cs b/Controllers/AtomFeed.cs
new file mode 100644
index 0000000..2260b4c
--- /dev/null
+++ b/Controllers/AtomFeed.cs
@@ -0,0 +1,35 @@
+using System.ServiceModel.Syndication;
+using Microsoft.AspNetCore.Mvc;
+using zotanpw.Backend;
+using zotanpw.Pages.blog;
+
+namespace zotanpw.Controllers;
+
+[ApiController]
+public class AtomFeed : Controller {
+ private static readonly string AtomXml;
+
+ static AtomFeed() {
+ var feed = new SyndicationFeed {
+ Id = "https://zotan.pw/blog",
+ Title = new TextSyndicationContent("zotan.pw >> blog"),
+ Description = new TextSyndicationContent("Blog of a disabled neurodivergent queer person unhappy with the state of the world"),
+ LastUpdatedTime = DateTimeOffset.Now,
+ Authors = { new SyndicationPerson("zotan@zotan.pw", "zotan", "https://zotan.pw") },
+ Items = BlogModel.Posts.Take(10)
+ .Select(post => new SyndicationItem(post.Title, new TextSyndicationContent(post.Content, TextSyndicationContentKind.Html),
+ new Uri($"https://zotan.pw/blog/{post.Shorthand}"), $"https://zotan.pw/blog/{post.Shorthand}",
+ post.PublishedOn.ToDateTime(TimeOnly.MinValue)))
+ .ToList(),
+ Links = { SyndicationLink.CreateSelfLink(new Uri("https://zotan.pw/blog/feed.atom")) }
+ };
+
+ AtomXml = new Atom10FeedFormatter(feed).ToXmlString();
+ }
+
+ [HttpGet, Route("/blog/feed.atom")]
+ public ActionResult GetAtomFeed() {
+ Response.ContentType = "application/atom+xml";
+ return Content(AtomXml);
+ }
+}
diff --git a/zotan.pw-web.csproj b/zotan.pw-web.csproj
index 4c2ec9c..e532e8f 100644
--- a/zotan.pw-web.csproj
+++ b/zotan.pw-web.csproj
@@ -13,6 +13,7 @@
+