115 lines
3.7 KiB
C#
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}";
|
|
}
|