From 81aceede76cf654db2d5e5e995c0aeaadd4b1c8a Mon Sep 17 00:00:00 2001
From: Demis Bellot
Date: Wed, 14 Feb 2024 04:28:13 +0800
Subject: [PATCH] implement missing components used in posts
---
.../src/_posts/2023-01-11_prerendering.md | 236 ------------------
.../2023-08-23_razor-ssg-new-blog-features.md | 5 +
.../_posts/2023-11-20_net8-blazor-template.md | 8 +-
.../src/_posts/2023-11-22_net8-best-blazor.md | 11 +-
.../src/_posts/components/BlazorTemplate.vue | 7 +
.../_posts/components/BlazorVueTemplate.vue | 7 +
MyApp.Client/src/_posts/components/ChartJs.ts | 31 +++
MyApp.Client/src/_posts/components/File.vue | 28 +++
.../src/_posts/components/FileLayout.vue | 12 +
MyApp.Client/src/_posts/components/Icons.ts | 0
.../src/_posts/components/TemplateIndex.ts | 38 +++
.../src/_posts/components/Templates.vue | 69 +++++
12 files changed, 210 insertions(+), 242 deletions(-)
delete mode 100644 MyApp.Client/src/_posts/2023-01-11_prerendering.md
create mode 100644 MyApp.Client/src/_posts/components/BlazorTemplate.vue
create mode 100644 MyApp.Client/src/_posts/components/BlazorVueTemplate.vue
create mode 100644 MyApp.Client/src/_posts/components/ChartJs.ts
create mode 100644 MyApp.Client/src/_posts/components/File.vue
create mode 100644 MyApp.Client/src/_posts/components/FileLayout.vue
create mode 100644 MyApp.Client/src/_posts/components/Icons.ts
create mode 100644 MyApp.Client/src/_posts/components/TemplateIndex.ts
create mode 100644 MyApp.Client/src/_posts/components/Templates.vue
diff --git a/MyApp.Client/src/_posts/2023-01-11_prerendering.md b/MyApp.Client/src/_posts/2023-01-11_prerendering.md
deleted file mode 100644
index bf03b7c..0000000
--- a/MyApp.Client/src/_posts/2023-01-11_prerendering.md
+++ /dev/null
@@ -1,236 +0,0 @@
----
-draft: true
-title: Prerendering Razor Pages
-summary: Improving Blog Performance with Prerendering
-author: Lucy Bates
-tags: [c#, dev, markdown]
-image: https://images.unsplash.com/photo-1522526886914-6e8d4fd91399?crop=entropy&fit=crop&h=1000&w=2000
----
-
-Prerendering static content is a popular technique used by [JAMStack](https://jamstack.org) Apps to improve the
-performance, reliability and scalability of Web Apps that's able to save unnecessary computation at runtime by
-generating static content at deployment which can be optionally hosted from a CDN for even greater performance.
-
-As such we thought it a valuable technique to include in this template to show how it can be easily achieved
-within a Razor Pages Application. Since prerendered content is only updated at deployment, it's primarily only
-useful for static content like this Blog which is powered by the static markdown content in
-[_blog/posts](https://github.com/NetCoreTemplates/vue-mjs/tree/main/MyApp/wwwroot/_blog/posts) whose content
-is prerendered to:
-
- - [/blog](https://vue-mjs.web-templates.io/blog)
-
-### Parsing Markdown Files
-
-All the functionality to load and render Markdown files is maintained in
-[Configure.Markdown.cs](https://github.com/NetCoreTemplates/vue-mjs/blob/main/MyApp/Configure.Markdown.cs),
-most of which is spent populating the POCO below from the content and frontmatter of each Markdown file:
-
-```csharp
-public class MarkdownFileInfo
-{
- public string Path { get; set; } = default!;
- public string? Slug { get; set; }
- public string? FileName { get; set; }
- public string? HtmlFileName { get; set; }
- public string? Title { get; set; }
- public string? Summary { get; set; }
- public string? Splash { get; set; }
- public string? Author { get; set; }
- public List Tags { get; set; } = new();
- public DateTime? Date { get; set; }
- public string? Content { get; set; }
- public string? Preview { get; set; }
- public string? HtmlPage { get; set; }
- public int? WordCount { get; set; }
- public int? LineCount { get; set; }
-}
-```
-
-Which uses the popular [Markdig](https://github.com/xoofx/markdig) library to parse the frontmatter into a
-Dictionary that it populates the POCO with using the built-in [Automapping](https://docs.servicestack.net/auto-mapping):
-
-```csharp
-var content = VirtualFiles.GetFile(path).ReadAllText();
-var document = Markdown.Parse(content, pipeline);
-var block = document
- .Descendants()
- .FirstOrDefault();
-var doc = block?
- .Lines // StringLineGroup[]
- .Lines // StringLine[]
- .Select(x => $"{x}\n")
- .ToList()
- .Select(x => x.Replace("---", string.Empty))
- .Where(x => !string.IsNullOrWhiteSpace(x))
- .Select(x => KeyValuePairs.Create(x.LeftPart(':').Trim(), x.RightPart(':').Trim()))
- .ToObjectDictionary()
- .ConvertTo();
-```
-
-Since this is a [Jekyll inspired blog](https://jekyllrb.com/docs/step-by-step/08-blogging/) it derives the **date** and **slug** for each
-post from its file name which has the nice property of maintaining markdown blog posts in chronological order:
-
-```csharp
-doc.Slug = file.Name.RightPart('_').LastLeftPart('.');
-doc.HtmlFileName = $"{file.Name.RightPart('_').LastLeftPart('.')}.html";
-
-var datePart = file.Name.LeftPart('_');
-if (DateTime.TryParseExact(datePart, "yyyy-MM-dd", CultureInfo.InvariantCulture,
- DateTimeStyles.AdjustToUniversal, out var date))
-{
- doc.Date = date;
-}
-```
-
-The rendering itself is done using Markdig's `HtmlRenderer` which renders the Markdown content into a HTML fragment:
-
-```csharp
-var pipeline = new MarkdownPipelineBuilder()
- .UseYamlFrontMatter()
- .UseAdvancedExtensions()
- .Build();
-var writer = new StringWriter();
-var renderer = new Markdig.Renderers.HtmlRenderer(writer);
-pipeline.Setup(renderer);
-//...
-
-renderer.Render(document);
-writer.Flush();
-doc.Preview = writer.ToString();
-```
-
-At this point we've populated Markdown Blog Posts into a POCO which is the data source used to implement all the blog's functionality.
-
-We can now start prerendering entire HTML Pages by rendering the markdown inside the
-[Post.cshtml](https://github.com/NetCoreTemplates/vue-mjs/blob/main/MyApp/Pages/Posts/Post.cshtml) Razor Page by populating its PageModel
-from the `MarkdownFileInfo` POCO. It also sets a `Static` flag that tells the Razor Page that this page is being statically rendered so
-it can render the appropriate links.
-
-```csharp
-var page = razorPages.GetView("/Pages/Posts/Post.cshtml");
-var model = new Pages.Posts.PostModel(this) { Static = true }.Populate(doc);
-doc.HtmlPage = RenderToHtml(page.View, model);
-
-public string RenderToHtml(IView? page, PageModel model)
-{
- using var ms = MemoryStreamFactory.GetStream();
- razorPages.WriteHtmlAsync(ms, page, model).GetAwaiter().GetResult();
- ms.Position = 0;
- var html = Encoding.UTF8.GetString(ms.ReadFullyAsMemory().Span);
- return html;
-}
-```
-
-The use of `GetResult()` on an async method isn't ideal, but something we have to live with until there's a better way
-to run async code on Startup.
-
-The actual rendering of the Razor Page is done with ServiceStack's `RazorPagesEngine` feature which sets up the necessary
-Http, View and Page contexts to render Razor Pages, registered in ASP.NET Core's IOC at:
-
-```csharp
-.ConfigureServices(services => {
- services.AddSingleton();
-})
-```
-
-The process of saving the prerendered content is then simply a matter of saving the rendered Razor Page at the preferred locations,
-done for each post and the [/blog](https://vue-mjs.web-templates.io/blog) index page using the
-[Posts/Index.cshtml](https://github.com/NetCoreTemplates/vue-mjs/blob/main/MyApp/Pages/Posts/Index.cshtml) Razor Page:
-
-```csharp
-foreach (var file in files)
-{
- // prerender /blog/{slug}.html
- if (renderTo != null)
- {
- log.InfoFormat("Writing {0}/{1}...", renderTo, doc.HtmlFileName);
- fs.WriteFile($"{renderTo}/{doc.HtmlFileName}", doc.HtmlPage);
- }
-}
-
-// prerender /blog/index.html
-if (renderTo != null)
-{
- log.InfoFormat("Writing {0}/index.html...", renderTo);
- RenderToFile(razorPages.GetView("/Pages/Posts/Index.cshtml").View,
- new Pages.Posts.IndexModel { Static = true }, $"{renderTo}/index.html");
-}
-```
-
-### Prerendering Pages Task
-
-Next we need to come up with a solution to run this from the command-line.
-[App Tasks](https://docs.servicestack.net/app-tasks) is ideal for this which lets you run one-off tasks within the full context of your App
-but without the overhead of maintaining a separate .exe with duplicated App configuration & logic, instead we can run the .NET App to
-run the specified Tasks then exit before launching its HTTP Server.
-
-To do this we'll register this task with the **prerender** AppTask name:
-
-```csharp
-AppTasks.Register("prerender", args => blogPosts.LoadPosts("_blog/posts", renderTo: "blog"));
-```
-
-Which we can run now from the command-line with:
-
-```bash
-$ dotnet run --AppTasks=prerender
-```
-
-To make it more discoverable, this is also registered as an npm script in `package.json`:
-
-```json
-{
- "scripts": {
- "prerender": "dotnet run --AppTasks=prerender"
- }
-}
-```
-
-That can now be run to prerender this blog to `/wwwroot/blog` with:
-
-```bash
-$ npm run prerender
-```
-
-### Prerendering at Deployment
-
-To ensure this is always run at deployment it's also added as an MS Build task in **MyApp.csproj**:
-
-```xml
-
-
-
-
-
-
-
-```
-
-Configured to run when the .NET App is published in the GitHub Actions deployment task in
-[/.github/workflows/release.yml](https://github.com/NetCoreTemplates/vue-mjs/blob/main/.github/workflows/release.yml):
-
-```yaml
- # Publish .NET Project
- - name: Publish dotnet project
- working-directory: ./MyApp
- run: |
- dotnet publish -c Release /p:APP_TASKS=prerender
-```
-
-Where it's able to control which App Tasks are run at deployment.
-
-### Pretty URLs for static .html pages
-
-A nicety we can add to serving static `.html` pages is giving them [Pretty URLs](https://en.wikipedia.org/wiki/Clean_URL)
-by registering the Plugin:
-
-```csharp
-Plugins.Add(new CleanUrlsFeature());
-```
-
-Which allows prerendered pages to be accessed with and without its file extension:
-
- - [/blog/prerendering](https://vue-mjs.web-templates.io/blog/prerendering)
- - [/blog/prerendering.html](https://vue-mjs.web-templates.io/blog/prerendering.html)
-
-###
\ No newline at end of file
diff --git a/MyApp.Client/src/_posts/2023-08-23_razor-ssg-new-blog-features.md b/MyApp.Client/src/_posts/2023-08-23_razor-ssg-new-blog-features.md
index e0fda55..b5b60ac 100644
--- a/MyApp.Client/src/_posts/2023-08-23_razor-ssg-new-blog-features.md
+++ b/MyApp.Client/src/_posts/2023-08-23_razor-ssg-new-blog-features.md
@@ -6,6 +6,11 @@ image: https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?crop=entropy
author: Lucy Bates
---
+
+
## New Blogging features in Razor SSG
[Razor SSG](https://razor-ssg.web-templates.io) is our Free Project Template for creating fast, statically generated Websites and Blogs with
diff --git a/MyApp.Client/src/_posts/2023-11-20_net8-blazor-template.md b/MyApp.Client/src/_posts/2023-11-20_net8-blazor-template.md
index 42bd663..090cd77 100644
--- a/MyApp.Client/src/_posts/2023-11-20_net8-blazor-template.md
+++ b/MyApp.Client/src/_posts/2023-11-20_net8-blazor-template.md
@@ -6,6 +6,10 @@ image: https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy
author: Lucy Bates
---
+
+
With the release of **.NET 8**, we're happy to announce ServiceStack's new [Blazor](https://blazor.web-templates.io/)
Tailwind project template that takes advantage of .NET 8 Blazor's new features that redefines modern Web Development in C#.
@@ -29,7 +33,7 @@ We’ll also discuss the project's structure, usage of **ASP.NET Core Identity**
Blazor Tailwind Template
-
+
@@ -40,7 +44,7 @@ We’ll also discuss the project's structure, usage of **ASP.NET Core Identity**
Create a new Blazor Tailwind project with your preferred project name:
-
+
## ASP.NET Core Identity Integration
diff --git a/MyApp.Client/src/_posts/2023-11-22_net8-best-blazor.md b/MyApp.Client/src/_posts/2023-11-22_net8-best-blazor.md
index 2e73ac5..8d29db6 100644
--- a/MyApp.Client/src/_posts/2023-11-22_net8-best-blazor.md
+++ b/MyApp.Client/src/_posts/2023-11-22_net8-best-blazor.md
@@ -6,13 +6,16 @@ image: https://images.unsplash.com/photo-1482686115713-0fbcaced6e28?crop=entropy
author: Gayle Smith
---
+
+
The best way to find out what's new in .NET 8 Blazor is to watch the excellent
[Full stack web UI with Blazor in .NET 8](https://www.youtube.com/watch?v=QD2-DwuOfKM) presentation by Daniel Roth and Steve Sanderson,
which covers how Blazor has become a Full Stack UI Web Technology for developing any kind of .NET Web App.
-
-
-
+
## Your first .NET 8 Blazor App
@@ -430,7 +433,7 @@ Vue.js to and the [Vue Components](/vue/) library.
Blazor Vue Template