PlotDirector/PlotLine/Controllers/HelpController.cs
2026-06-24 10:09:07 +01:00

115 lines
3.7 KiB
C#

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using PlotLine.Services;
using PlotLine.ViewModels;
using System.Net;
namespace PlotLine.Controllers;
[Route("help")]
[AllowAnonymous]
public sealed class HelpController(IHelpService help, IHelpMarkdownRenderer markdown) : Controller
{
[HttpGet("")]
public IActionResult Index(string? q)
{
if (!IsCanonicalPath("/help"))
{
return RedirectPermanent(PreserveQuery("/help"));
}
ViewData["CanonicalUrl"] = "https://plotdirector.com/help";
var articles = help.GetAllArticles();
return View(new HelpCentreIndexViewModel
{
Query = q,
ArticleCount = articles.Count,
Categories = help.GetCategories()
.Select(category => new HelpCategoryViewModel
{
CategoryName = category,
CategorySlug = HelpService.Slugify(category),
ArticleCount = help.GetByCategory(category).Count
})
.ToList(),
SearchResults = string.IsNullOrWhiteSpace(q) ? [] : help.Search(q),
RecentArticles = articles.OrderByDescending(x => x.RelativePath).Take(5).ToList()
});
}
[HttpGet("{categorySlug}")]
public IActionResult Category(string categorySlug)
{
var category = help.GetCategoryBySlug(categorySlug);
if (category is null)
{
return NotFound();
}
var canonicalPath = $"/help/{HelpService.Slugify(category)}";
if (!IsCanonicalPath(canonicalPath))
{
return RedirectPermanent(canonicalPath);
}
var articles = help.GetByCategorySlug(categorySlug);
ViewData["CanonicalUrl"] = $"https://plotdirector.com{canonicalPath}";
return View(new HelpCategoryArticlesViewModel
{
CategoryName = category,
CategorySlug = HelpService.Slugify(category),
Articles = articles
});
}
[HttpGet("{categorySlug}/{articleSlug}")]
public IActionResult Article(string categorySlug, string articleSlug)
{
var article = help.GetBySlugs(categorySlug, articleSlug);
if (article is null)
{
return View("ArticleNotFound", $"{categorySlug}/{articleSlug}");
}
if (!IsCanonicalPath(article.Url))
{
return RedirectPermanent(article.Url);
}
ViewData["CanonicalUrl"] = $"https://plotdirector.com{article.Url}";
return View(new HelpCentreArticleViewModel
{
Article = article,
RenderedHtml = markdown.Render(article.MarkdownContent),
RelatedArticles = help.GetRelatedArticles(article)
});
}
[HttpGet("/Help/Category/{category}")]
public IActionResult LegacyCategory(string category)
{
var articles = help.GetByCategory(WebUtility.UrlDecode(category));
var firstArticle = articles.FirstOrDefault();
return firstArticle is null
? NotFound()
: RedirectPermanent(firstArticle.CategoryUrl);
}
[HttpGet("/Help/Article/{key}")]
public IActionResult LegacyArticle(string key)
{
var article = help.GetByContextKey(WebUtility.UrlDecode(key));
return article is null
? View("ArticleNotFound", key)
: RedirectPermanent(article.Url);
}
private bool IsCanonicalPath(string path) =>
string.Equals(HttpContext.Request.Path.Value, path, StringComparison.Ordinal);
private string PreserveQuery(string path) =>
string.IsNullOrWhiteSpace(HttpContext.Request.QueryString.Value)
? path
: $"{path}{HttpContext.Request.QueryString.Value}";
}