feat: add individual post page (#4)
* chore: add markdown lint to ignore no h1 heading in markdown files * chore: update example settings * chore: update example development env file * fix: remove fixed 100% height on container * feat: add individual post page * chore: update README.md * feat: add links to headings in post and add copy button to code blocks * tests: add tests for get post async method * tests: remove heading for test blogs * fix: only add links to headings in markdown body * tests: add tests for post page * tests: add test to check for blog content * docs: add jsdoc comments * chore: fix incorrect env variable format in example * fix: don't render anything if blog post is null * fix: don't render anything until posts are fetched * chore: add docker compose file for prod
This commit is contained in:
@@ -105,4 +105,46 @@ class FilePostService(
|
||||
|
||||
return [.. posts.OrderByDescending(x => x.PublishedAt)];
|
||||
}
|
||||
|
||||
public async Task<PostWithContent?> GetPostAsync(string slug)
|
||||
{
|
||||
try
|
||||
{
|
||||
var postPath = _fileSystem.Path.Combine(_options.PostsDirectory, slug, IndexFile);
|
||||
|
||||
if (_fileSystem.File.Exists(postPath) is false)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var postText = await _fileSystem.File.ReadAllTextAsync(postPath);
|
||||
|
||||
var (metaContent, document) = ParsePost(postText);
|
||||
|
||||
if (metaContent is null || document.Count is 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var post = JsonSerializer.Deserialize<PostWithContent>(metaContent, JsonSerializerOptions);
|
||||
|
||||
if (post is null || post.IsPublished is false)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var postWithContent = post with
|
||||
{
|
||||
Slug = slug,
|
||||
Content = document.ToHtml(MarkdownPipeline)
|
||||
};
|
||||
|
||||
return postWithContent;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error while getting post {Slug}", slug);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,4 +3,5 @@ namespace Blog.Posts;
|
||||
interface IPostService
|
||||
{
|
||||
Task<List<Post>> GetPostsAsync();
|
||||
Task<PostWithContent?> GetPostAsync(string slug);
|
||||
}
|
||||
Reference in New Issue
Block a user