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:
Stevan Freeborn
2024-04-11 00:58:22 -05:00
committed by GitHub
parent 75831e5f45
commit dd7e7e1783
19 changed files with 1774 additions and 13 deletions
+42
View File
@@ -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;
}
}
}
+1
View File
@@ -3,4 +3,5 @@ namespace Blog.Posts;
interface IPostService
{
Task<List<Post>> GetPostsAsync();
Task<PostWithContent?> GetPostAsync(string slug);
}