perf: handle content processing in BlogService
This commit is contained in:
parent
983e636635
commit
aaafcaf760
|
@ -1,6 +1,8 @@
|
|||
@page "/blog/{year:int}/{month:int}/{day:int}/{slug}"
|
||||
@page "/blog/{year:int}/{month:int}/{day:int}/{slug}"
|
||||
@using Humanizer
|
||||
@using OliverBooth.Services
|
||||
@model OliverBooth.Pages.Blog.Article
|
||||
@inject BlogService BlogService
|
||||
|
||||
@if (Model.Post is not { } post)
|
||||
{
|
||||
|
@ -39,7 +41,7 @@
|
|||
</p>
|
||||
|
||||
<article>
|
||||
@Html.Raw(Model.SanitizeContent(post.Body))
|
||||
@Html.Raw(BlogService.GetContent(post))
|
||||
</article>
|
||||
|
||||
<hr>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using Markdig;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using OliverBooth.Data.Blog;
|
||||
using OliverBooth.Services;
|
||||
|
@ -12,17 +11,14 @@ namespace OliverBooth.Pages.Blog;
|
|||
public class Article : PageModel
|
||||
{
|
||||
private readonly BlogService _blogService;
|
||||
private readonly MarkdownPipeline _markdownPipeline;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Article" /> class.
|
||||
/// </summary>
|
||||
/// <param name="blogService">The <see cref="BlogService" />.</param>
|
||||
/// <param name="markdownPipeline">The <see cref="MarkdownPipeline" />.</param>
|
||||
public Article(BlogService blogService, MarkdownPipeline markdownPipeline)
|
||||
public Article(BlogService blogService)
|
||||
{
|
||||
_blogService = blogService;
|
||||
_markdownPipeline = markdownPipeline;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -45,23 +41,6 @@ public class Article : PageModel
|
|||
/// <value>The requested blog post.</value>
|
||||
public BlogPost Post { get; private set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Sanitizes the content of the blog post.
|
||||
/// </summary>
|
||||
/// <param name="content">The content of the blog post.</param>
|
||||
/// <returns>The sanitized content of the blog post.</returns>
|
||||
public string SanitizeContent(string content)
|
||||
{
|
||||
content = content.Replace("<!--more-->", string.Empty);
|
||||
|
||||
while (content.Contains("\n\n"))
|
||||
{
|
||||
content = content.Replace("\n\n", "\n");
|
||||
}
|
||||
|
||||
return Markdown.ToHtml(content.Trim(), _markdownPipeline);
|
||||
}
|
||||
|
||||
public IActionResult OnGet(int year, int month, int day, string slug)
|
||||
{
|
||||
if (!_blogService.TryGetBlogPost(year, month, day, slug, out BlogPost? post))
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
}
|
||||
</p>
|
||||
|
||||
<p>@Html.Raw(Model.SanitizeContent(Model.TrimContent(post.Body, out bool trimmed)))</p>
|
||||
<p>@Html.Raw(BlogService.GetExcerpt(post, out bool trimmed))</p>
|
||||
|
||||
<article>
|
||||
@if (trimmed)
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
using System.Diagnostics;
|
||||
using Humanizer;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using OliverBooth.Data.Blog;
|
||||
using OliverBooth.Services;
|
||||
|
@ -16,26 +14,6 @@ public class Index : PageModel
|
|||
_blogService = blogService;
|
||||
}
|
||||
|
||||
public string SanitizeContent(string content)
|
||||
{
|
||||
content = content.Replace("<!--more-->", string.Empty);
|
||||
|
||||
while (content.Contains("\n\n"))
|
||||
{
|
||||
content = content.Replace("\n\n", "\n");
|
||||
}
|
||||
|
||||
return Markdig.Markdown.ToHtml(content.Trim());
|
||||
}
|
||||
|
||||
public string TrimContent(string content, out bool trimmed)
|
||||
{
|
||||
ReadOnlySpan<char> span = content.AsSpan();
|
||||
int moreIndex = span.IndexOf("<!--more-->", StringComparison.Ordinal);
|
||||
trimmed = moreIndex != -1 || span.Length > 256;
|
||||
return moreIndex != -1 ? span[..moreIndex].Trim().ToString() : content.Truncate(256);
|
||||
}
|
||||
|
||||
public IActionResult OnGet([FromQuery(Name = "pid")] int? postId = null,
|
||||
[FromQuery(Name = "p")] int? wpPostId = null)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Humanizer;
|
||||
using Markdig;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OliverBooth.Data;
|
||||
using OliverBooth.Data.Blog;
|
||||
|
@ -8,14 +10,17 @@ namespace OliverBooth.Services;
|
|||
public sealed class BlogService
|
||||
{
|
||||
private readonly IDbContextFactory<BlogContext> _dbContextFactory;
|
||||
private readonly MarkdownPipeline _markdownPipeline;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BlogService" /> class.
|
||||
/// </summary>
|
||||
/// <param name="dbContextFactory">The <see cref="IDbContextFactory{TContext}" />.</param>
|
||||
public BlogService(IDbContextFactory<BlogContext> dbContextFactory)
|
||||
/// <param name="markdownPipeline">The <see cref="MarkdownPipeline" />.</param>
|
||||
public BlogService(IDbContextFactory<BlogContext> dbContextFactory, MarkdownPipeline markdownPipeline)
|
||||
{
|
||||
_dbContextFactory = dbContextFactory;
|
||||
_markdownPipeline = markdownPipeline;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -31,6 +36,34 @@ public sealed class BlogService
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the processed content of a blog post.
|
||||
/// </summary>
|
||||
/// <param name="post">The blog post.</param>
|
||||
/// <returns>The processed content of the blog post.</returns>
|
||||
public string GetContent(BlogPost post)
|
||||
{
|
||||
return ProcessContent(post.Body);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the processed excerpt of a blog post.
|
||||
/// </summary>
|
||||
/// <param name="post">The blog post.</param>
|
||||
/// <param name="trimmed">
|
||||
/// When this method returns, contains <see langword="true" /> if the content was trimmed; otherwise,
|
||||
/// <see langword="false" />.
|
||||
/// </param>
|
||||
/// <returns>The processed excerpt of the blog post.</returns>
|
||||
public string GetExcerpt(BlogPost post, out bool trimmed)
|
||||
{
|
||||
ReadOnlySpan<char> span = post.Body.AsSpan();
|
||||
int moreIndex = span.IndexOf("<!--more-->", StringComparison.Ordinal);
|
||||
trimmed = moreIndex != -1 || span.Length > 256;
|
||||
string result = moreIndex != -1 ? span[..moreIndex].Trim().ToString() : post.Body.Truncate(256);
|
||||
return ProcessContent(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to find the author of a blog post.
|
||||
/// </summary>
|
||||
|
@ -106,4 +139,16 @@ public sealed class BlogService
|
|||
post = context.BlogPosts.FirstOrDefault(p => p.WordPressId == postId);
|
||||
return post is not null;
|
||||
}
|
||||
|
||||
private string ProcessContent(string content)
|
||||
{
|
||||
content = content.Replace("<!--more-->", string.Empty);
|
||||
|
||||
while (content.Contains("\n\n"))
|
||||
{
|
||||
content = content.Replace("\n\n", "\n");
|
||||
}
|
||||
|
||||
return Markdown.ToHtml(content.Trim(), _markdownPipeline);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue