上一篇文章做到的進度是:
能讀DB抓文章進Views
能根據傳進Views的Data產生文章列表
能點進去看內文
那基本上Blog最最基礎的部份就達成了,接下來應該開始寫文章,不然其他功能都用不到
當初計劃本站的時候是打算把文章用markdown語法儲存在DB
再找方法把markdown parse成html顯示出來
所以blog table的欄位也寫明是markdown_content
首先要有一個Blog Create的頁面
新增View Controller這些就不再詳述了
總之我們有一個Controller,裡面有一個Method會接收GET request,return 新增的Create.cshtml這個view
另外有一個Method是接收POST request,會把傳來的blog object寫進DB。
Create.cshtml長這樣:
@model Blog
@{
}
<head>
@*<script src="https://cdn.ckeditor.com/ckeditor5/22.0.0/classic/ckeditor.js"></script>*@
@if (TempData["Message"] != null)
{
<script type="text/javascript">
var message = @Html.Raw(Json.Serialize(TempData["Message"]));
alert(message);
</script>
}
</head>
<h2>Create Blog</h2>
<div id="blogBody" class="col-md-9 col-sm-12 col-12 bottom">
<p>@TempData["ip"]</p>
<form action="/Blog/Create")" method="post">
<div class="form-group">
<label class="col-md-2" asp-for="Title" for="title">Title</label>
<input class="col-md-8" asp-for="Title" type="text" name="title" id="title" />
<span asp-validation-for="Title" class="text-danger col-md-1 small"></span>
</div>
<div class="form-group">
<label class="col-md-2" asp-for="Category" for="category">Category</label>
<input class="col-md-8" asp-for="Category" type="text" name="Category" id="category" />
<span asp-validation-for="Category" class="text-danger col-md-1 small"></span>
</div>
<div class="form-group">
<label class="col-md-2" asp-for="Tags" for="tags">Tags</label>
<input class="col-md-8" asp-for="Tags" type="text" name="tags" id="tags" />
<span asp-validation-for="Tags" class="text-danger col-md-1 small"></span>
</div>
<div class="form-group">
<label class="col-md-2" asp-for="Password" for="password">Password</label>
<input class="col-md-4" asp-for="Password" type="password" name="password" value="" id="password" />
<span asp-validation-for="Password" class="text-danger col-md-1 small"></span>
</div>
<div class="form-group">
<label class="col-md-2" asp-for="NoComment" for="noComment">No Comment</label>
<input class="col-md-1" asp-for="NoComment" type="checkbox" name="no_Comment" id="noComment" />
<span asp-validation-for="NoComment" class="text-danger col-md-1 small"></span>
</div>
<div class="form-group">
<label class="col-md-2" asp-for="NoRobots" for="noRobots">No Robots</label>
<input class="col-md-1" asp-for="NoRobots" type="checkbox" name="no_Robots" id="noRobots" />
<span asp-validation-for="NoRobots" class="text-danger"></span>
</div>
<div class="form-group">
<label class="col-md-2" for="content" style="vertical-align:top">Content</label>
<textarea class="col-md-8" name="markdown_Content" id="content" style="height:500px"></textarea>
<script src="~/lib/ckeditor/ckeditor.js"></script>
<script>
// Replace the <textarea id="editor1"> with a CKEditor 4
// instance, using default configuration.
var editor = CKEDITOR.replace('content');
</script>
@if (ViewData["EditMode"] != null && (Boolean)ViewData["EditMode"])
{
<script>
editor.on('instanceReady', function () {
editor.insertHtml(`@Html.Raw(Model.Markdown_Content)`);
});
</script>
}
@*below querySelector('#content') meant replace the element of id="content"*@
@*
<script>
ClassicEditor
.create(document.querySelector('#content'), {
codeBlock: {
languages: [{ language: 'cs', label: 'C#' },
{ language: 'cpp', label: 'C++' },
{ language: 'css', label: 'CSS' },
{ language: 'html', label: 'HTML' },
{ language: 'java', label: 'Java' },
{ language: 'javascript', label: 'JavaScript' },
{ language: 'python', label: 'Python' }]
}
})
.catch(error => {
console.error(error);
});
</script>
*@
</div>
<hr style="border-top:1px solid #eee" />
<input type="submit" value="Submit" class="btn btn-default" style="border:1px solid black;" />
</form>
</div>
<partial name="~/Views/Shared/_sidebar.cshtml" />
很長的一段...
所以以下會有詳解
<form action="/Blog/Create" method="post">
<div class="form-group">
<label class="col-md-2" asp-for="Title" for="title">Title</label>
<input class="col-md-8" asp-for="Title" type="text" name="title" id="title" />
<span asp-validation-for="Title" class="text-danger col-md-1 small"></span>
</div>
.
.
.
<div class="form-group">
<label class="col-md-2" for="content" style="vertical-align:top">Content</label>
<textarea class="col-md-8" name="markdown_Content" id="content" style="height:500px"></textarea>
</div>
<input type="submit" value="Submit" class="btn btn-default" style="border:1px solid black;" />
</form>
Create頁面內主要目的是填入一個blog所需的一切資料,然後POST到某個url去
<form>的用途就是負責POST的動作
form裡面有好幾組<label>和<input>,label如其名只是一個文字標籤,當中的for是指這個label是哪個id的label,asp-for則指向它屬於model內的哪一個property。<span>使用了asp-validation-for,當表單輸入資料有誤時,這個span會顯示錯誤文字
當我們按下Submit時,所有input的value都會被封進POST request內傳送出去,詳情可以看下面:
https://developer.mozilla.org/en-US/docs/Learn/Forms/Sending_and_retrieving_form_data
<div class="form-group">
<label class="col-md-2" for="content" style="vertical-align:top">Content</label>
<textarea class="col-md-8" name="markdown_Content" id="content" style="height:500px"></textarea>
<script src="~/lib/ckeditor/ckeditor.js"></script>
<script>
// Replace the <textarea id="editor1"> with a CKEditor 4
// instance, using default configuration.
var editor = CKEDITOR.replace('content');
</script>
@*below querySelector('#content') meant replace the element of id="content"*@
@*
<script>
ClassicEditor
.create(document.querySelector('#content'), {
codeBlock: {
languages: [{ language: 'cs', label: 'C#' },
{ language: 'cpp', label: 'C++' },
{ language: 'css', label: 'CSS' },
{ language: 'html', label: 'HTML' },
{ language: 'java', label: 'Java' },
{ language: 'javascript', label: 'JavaScript' },
{ language: 'python', label: 'Python' }]
}
})
.catch(error => {
console.error(error);
});
</script>
*@
</div>
Blog的markdown_content,由一個textarea的值輸入。
我們當初預期blog的內容是由markdown語法轉化html而成,裡面應可包含圖片、文字、超連結等內容,這很明顯不是一個textarea足以處理的,我們需要一個多功能的文本編輯器,如同microsoft word一樣。這裡用上CKEditor,引用在官網下載的js,執行script,替換id為content的textarea,這個插件可以提供超級豐富的文檔編輯功能,比如格式、插入圖片、插入youtube連結、emoji還有很多很多不同的選用功能,並且最後輸出成Html格式。
由於太好用,所以最後欄位還是叫markdown_content,但實際上是html,我也爛得改。
最後沒有使用CKEditor 5的原因是,它太新,插件不足。
總結一下,我們新增了一個Create blog的頁面,裡面有一個form,包含了blog物件的大部份所需欄位,比如title、content等,並且引入了CKEditor作為編輯器,寫好文章後按submit,form的各種input打包成post request的body,發出POST request到/Blog/Create,Controller的Method收到這個POST request後就會從後台找相關class把Post request的body(即blog)寫進DB,最後回到首頁便能看到相關文章。
加入了Collection功能
根本誰都不會用facebook account留言