PlotDirector/PlotLine/Controllers/SitemapController.cs

91 lines
3.2 KiB
C#

using System.Text;
using System.Xml;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using PlotLine.Models;
using PlotLine.Services;
namespace PlotLine.Controllers;
[AllowAnonymous]
public sealed class SitemapController(IHelpService help, IConfiguration configuration) : Controller
{
[HttpGet("/sitemap.xml")]
public IActionResult Index()
{
var urls = new List<SitemapUrl>
{
new("/", "weekly", "1.0"),
new("/pricing", "weekly", "0.8"),
new("/help", "weekly", "0.7"),
new("/about", "monthly", "0.6"),
new("/contact", "monthly", "0.5"),
new("/privacy", "yearly", "0.3"),
new("/terms", "yearly", "0.3")
};
var articles = help.GetAllArticles();
urls.AddRange(articles
.Where(article => !string.IsNullOrWhiteSpace(article.CategorySlug))
.GroupBy(article => article.CategorySlug, StringComparer.OrdinalIgnoreCase)
.OrderBy(group => group.Key, StringComparer.OrdinalIgnoreCase)
.Select(group => new SitemapUrl(
$"/help/{group.Key}",
"monthly",
"0.6",
group.Max(article => article.LastModifiedUtc))));
urls.AddRange(articles
.Where(article => !string.IsNullOrWhiteSpace(article.CategorySlug) && !string.IsNullOrWhiteSpace(article.Slug))
.OrderBy(article => article.CategorySlug, StringComparer.OrdinalIgnoreCase)
.ThenBy(article => article.Slug, StringComparer.OrdinalIgnoreCase)
.Select(article => new SitemapUrl(
article.Url,
"monthly",
"0.5",
article.LastModifiedUtc)));
return Content(BuildXml(urls), "application/xml", Encoding.UTF8);
}
private string BuildXml(IEnumerable<SitemapUrl> urls)
{
var settings = new XmlWriterSettings
{
Encoding = new UTF8Encoding(false),
Indent = true,
OmitXmlDeclaration = false
};
using var writer = new Utf8StringWriter();
using var xml = XmlWriter.Create(writer, settings);
xml.WriteStartDocument();
xml.WriteStartElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");
foreach (var url in urls)
{
xml.WriteStartElement("url");
xml.WriteElementString("loc", PublicSeo.AbsoluteUrl(configuration, url.Path));
if (url.LastModifiedUtc is DateTime lastModifiedUtc && lastModifiedUtc != default)
{
xml.WriteElementString("lastmod", lastModifiedUtc.ToString("yyyy-MM-dd"));
}
xml.WriteElementString("changefreq", url.ChangeFrequency);
xml.WriteElementString("priority", url.Priority);
xml.WriteEndElement();
}
xml.WriteEndElement();
xml.WriteEndDocument();
xml.Flush();
return writer.ToString();
}
private sealed record SitemapUrl(string Path, string ChangeFrequency, string Priority, DateTime? LastModifiedUtc = null);
private sealed class Utf8StringWriter : StringWriter
{
public override Encoding Encoding => Encoding.UTF8;
}
}