📖
.NET Core Blazor + MicroCMSでブログサイト作成⑦
今回の内容は
- ブログ記事をタグで絞り込む
- ブログ記事ページ作成
です。
ラッキーセブンとよく言いますが、由来はアメリカの野球にあるそうです。
タグ絞り込み
ただのイベント処理です。
Blog.razor
//抜粋
@page "/blog"
@using BlazorBlog.Shared.MicroCMS
@inject HttpClient Http
@if (sitedata == null || tag == null || blog == null)
{
...
}
else
{
<h1>@sitedata.BlogTitle</h1>
<div class="mb-3">
@foreach (TagContents contents in tag.TagList)
{
<!-- @onclickを追加 -->
<button type="button" class="btn btn-dark btn-sm rounded-pill mx-2" @onclick="@(e => TagSelected(contents.Id))">@contents.Name</button>
}
</div>
...
}
@code {
private SiteDataModel sitedata;
private TagModel tag;
private BlogModel blog;
protected override async Task OnInitializedAsync()
{
// ...
}
// 追加
private async Task TagSelected(string tagId)
{
try
{
blog = await Http.GetFromJsonAsync<BlogModel>($"MicroCMS/BlogList/{tagId}");
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
appsettings.json
// 抜粋
"MicroCMS": {
// ...
"QueryParam": {
"SiteData": "?fields=title",
"TagList": "?fields=id,name",
"BlogList": "?fields=title,publishedAt,tag.id,tag.name",
// 追加
"BlogListByTag": "?filters=tag[equals]#id"
}
}
MicroCMSController.cs
// 抜粋
namespace BlazorBlog.Server.Controllers
{
[ApiController]
[Route("[controller]")]
public class MicroCMSController : ControllerBase
{
// ...
// 追加
[Route("BlogList/{tagId}")]
public async Task<BlogModel> GetBlogListByTag(string tagId)
{
string url = apiSettings.BaseUrl + apiSettings.Endpoints.BlogList
+ "?" + apiSettings.QueryParam.BlogList
+ "&" + apiSettings.QueryParam.BlogListByTag.Replace("#id", tagId);
string apikey = apiSettings.ApiKey;
BlogModel result = await Fetch<BlogModel>(url, apikey);
return result;
}
// ...
}
}
実行してみます。MicroCMSには3つのタグが登録してあり、
- 「数学」⇒使用していない
- 「ブログ」⇒テスト1,テスト2,テスト5
- 「Minecraft」⇒テスト3、テスト4
となっています。上記のとおりにフィルタリングされることを確認します。
「数学」を押すと
「Minecraft」を押すと
「ブログ」を押すと
と、正しくフィルタリングできました。
なんだかブログらしくなってきました。
取得データもちゃんと必要な項目だけになってます。(「ブログ」クリック時)
ブログ記事ページ作成
ブログ一覧の各タイトルをクリックするとコンテンツページに飛ぶようにつくります。
タイトルをリンク化
Shared/BlogCard.razor
<div class="row my-2 d-flex justify-content-center">
<div class="col-12 col-md-8 text-truncate cardbox">
<div class="m-3">
<!-- pタグからaタグに変更 -->
<a href="blog/@blogId">@title</a>
<div>Tag:@tag</div>
<div>Publish:@publishedAt.ToLocalTime().ToString("yyyy/MM/dd")</div>
</div>
</div>
</div>
@code {
// 追加
[Parameter]
public string blogId { get; set; }
[Parameter]
public string title { get; set; }
[Parameter]
public string tag { get; set; }
[Parameter]
public DateTime publishedAt { get; set; }
}
設定値、アクションの追加
コンテンツIDがあれば本文データを取得可能です。
MicroCMS APIにはblog/コンテンツIDにリクエストを送ると、指定したコンテンツIDを持つコンテンツのみを返す機能があります。(もちろんクエリパラメータで項目を絞ることは可能です)
appsettings.json
// 抜粋
"QueryParam": {
"SiteData": "?fields=title",
"TagList": "?fields=id,name",
"BlogList": "?fields=id,title,publishedAt,tag.id,tag.name",
"BlogListByTag": "?filters=tag[equals]#id",
// 追加
"BlogContents": "?fields=title,tag.name,publishedAt,body"
}
MicroCMSSettingModel
// 抜粋
namespace BlazorBlog.Server
{
// ...
public class MicroCMSQueryParamSettingModel
{
public string SiteData { get; set; }
public string TagList { get; set; }
public string BlogList { get; set; }
public string BlogListByTag { get; set; }
// 追加
public string BlogContents { get; set; }
}
}
MicroCMSController.cs
// 抜粋
namespace BlazorBlog.Server.Controllers
{
[ApiController]
[Route("[controller]")]
public class MicroCMSController : ControllerBase
{
// ...
// 追加
[Route("BlogContents/{blogId}")]
public async Task<BlogContents> GetBlogContents(string blogId)
{
string url = apiSettings.BaseUrl + apiSettings.Endpoints.BlogContents.Replace("#id", blogId)
+ "?" + apiSettings.QueryParam.BlogContents;
string apikey = apiSettings.ApiKey;
BlogContents result = await Fetch<BlogContents>(url, apikey);
return result;
}
}
ブログ記事ページ
スタイリングは後回しで。
BlogPage.razor
@page "/blog/{blogId}"
@using BlazorBlog.Shared.MicroCMS
@inject HttpClient Http
@if (contents == null)
{
<div class="d-flex justify-content-center">
<div class="spinner-border" style="width: 3rem; height: 3rem;" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
}
else
{
<h3>@contents.Title</h3>
<p>Tag:@contents.Tag.Name</p>
<p>Publish:@contents.PublishedAt.ToLocalTime().ToString("yyyy/MM/dd")</p>
<div>
@((MarkupString)contents.Body)
</div>
}
@code {
[Parameter]
public string blogId { get; set; }
private BlogContents contents;
protected override async Task OnInitializedAsync()
{
try
{
contents = await Http.GetFromJsonAsync<BlogContents>($"MicroCMS/BlogContents/{blogId}");
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
HTMLをそのまま、文字列としてHTMLが表示されてしまします。
正しく表示させるには、MarkupStringにキャストする必要があります👇
@((MarkupString)contents.Body)
実行
👇
めでたく表示できました。
次回
- ブログ記事ページに機能追加、スタイリング
- 一覧に戻るリンク
- 次の記事/前の記事リンク
- シンタックスハイライト(Highlight.js)
Discussion