基于.NetCore開發博客項目 StarBlog - (7) 頁面開發之文章詳情頁面

系列文章

  • 基于.NetCore開發博客項目 StarBlog - (1) 為什么需要自己寫一個博客?

  • 基于.NetCore開發博客項目 StarBlog - (2) 環境準備和創建項目

  • 基于.NetCore開發博客項目 StarBlog - (3) 模型設計

  • 基于.NetCore開發博客項目 StarBlog - (4) markdown博客批量導入

  • 基于.NetCore開發博客項目 StarBlog - (5) 開始搭建Web項目

  • 基于.NetCore開發博客項目 StarBlog - (6) 頁面開發之博客文章列表

  • 基于.NetCore開發博客項目 StarBlog - (7) 頁面開發之文章詳情頁面

  • ...

前言

前一篇博客完成了文章列表的開發,現在要來寫文章詳情頁面了(這篇更新應該沒遲到吧,嘿嘿)。

博客網站最重要的可以說就是文章詳情頁面了,用戶來看博客最關心首先是內容,其次是閱讀體驗,所以這個文章詳情頁面的設計不能馬虎~

思路

文章正文是以markdown格式存儲的,要在網頁上展示的話,需要把markdown渲染成HTML才行。

那么就有兩種思路:

  • 一種是在后端渲染,使用C#把markdown轉換成HTML然后渲染成網頁

  • 另一種是后端直接輸出markdown,使用一些開源的JS庫實現markdown渲染

一開始我是采用第一種的后端渲染方式,用到的C#庫是Markdig,不過深入使用之后發現有一些想要的功能實現起來比較麻煩,特別是這個庫幾乎沒有文檔,要自定義一些功能全靠看源碼+猜,最后只能放棄轉而使用第二種方式。

本文對兩種方式的實現都會介紹,著重介紹第二種前端渲染。

后端渲染

關于Markdig這個庫的我之前寫的博客有詳細的介紹,這里不再重復,有興趣的同學可以看看:C#解析Markdown文檔,實現替換圖片鏈接操作

首先Nuget安裝Markdig這個庫

一行代碼就可以實現markdown轉HTML

Markdig.Markdown.ToHtml(markdownContent);

當然直接渲染出來的頁面是很簡陋的,沒有代碼高亮、沒有引用塊、沒有列表樣式啥的,所以單純這樣肯定是不夠的。

Markdig作為C#目前唯一積極維護的Markdown庫,自然是考慮到了擴展性,它設計了擴展系統,本身內置了20多個擴展,還可以安裝其他人開發的擴展用來實現例如代碼高亮的效果。

使用擴展也很簡單,加個pipeline參數就行

var?pipeline?=?new?MarkdownPipelineBuilder().UseAdvancedExtensions().Build();
var?result?=?Markdown.ToHtml("This?is?a?text?with?some?*emphasis*",?pipeline);

Markdig本身不自帶代碼高亮擴展,需要使用第三方組件,我測試了下面這兩個能用

  • Markdig.Prism:前端渲染,但需要服務端組件配合

  • Markdown.ColorCode:服務端渲染

前端渲染

本項目最終選了前端渲染的方案,前端生態有眾多的markdown組件,看了一圈之后我最終選了Editor.md這個組件。

主要看中它可以比較方便的實現文章的TOC(目錄)功能,還有不錯的高亮效果。

使用起來很簡單

首先把markdown輸出到網頁里

<div?id="test-editormd-view"?class="post-content"><textarea?id="append-test"?style="display:none;">@Model.Content</textarea>
</div>

加了display:none不顯示這個textarea,給用戶看markdown代碼沒用

引入edtor.md的樣式文件

<link?rel="stylesheet"?href="~/lib/editormd/css/editormd.preview.min.css">

引入editor.md的js,你沒看錯,就是這么多。靜態資源在之前的文章里已經安裝好了,這里不再重復。詳見:(5) 開始搭建Web項目

<script?src="~/lib/editormd/examples/js/jquery.min.js"></script>
<script?src="~/lib/editormd/lib/marked.min.js"></script>
<script?src="~/lib/editormd/lib/prettify.min.js"></script><script?src="~/lib/editormd/lib/raphael.min.js"></script>
<script?src="~/lib/editormd/lib/underscore.min.js"></script>
<script?src="~/lib/editormd/lib/sequence-diagram.min.js"></script>
<script?src="~/lib/editormd/lib/flowchart.min.js"></script>
<script?src="~/lib/editormd/lib/jquery.flowchart.min.js"></script><script?src="~/lib/editormd/editormd.min.js"></script>

然后,使用js調用editor.md的渲染方法

let?testEditormdView?=?editormd.markdownToHTML("test-editormd-view",?{//?htmlDecode:?"style,script,iframe",??//?you?can?filter?tags?decodehtmlDecode:?true,//toc?????????????:?false,tocm:?true,????//?Using?[TOCM]tocContainer:?"#custom-toc-container",?//?自定義?ToC?容器層//gfm?????????????:?false,//tocDropdown?????:?true,//?markdownSourceCode?:?true,?//?是否保留?Markdown?源碼,即是否刪除保存源碼的?Textarea?標簽emoji:?true,taskList:?true,tex:?true,??//?默認不解析flowChart:?true,??//?默認不解析sequenceDiagram:?true,??//?默認不解析
})

搞定。

ViewModel

Post模型只是存在數據庫中的數據,直接展示不能完全滿足網頁設計的需求,所以還是一樣,需要定義一個ViewModel來用。

依然是放在StarBlog.Web/ViewModels

代碼如下

public?class?PostViewModel?{public?string?Id?{?get;?set;?}public?string?Title?{?get;?set;?}public?string?Summary?{?get;?set;?}public?string?Content?{?get;?set;?}public?string?ContentHtml?{?get;?set;?}public?string?Path?{?get;?set;?}public?DateTime?CreationTime?{?get;?set;?}public?DateTime?LastUpdateTime?{?get;?set;?}public?Category?Category?{?get;?set;?}public?List<Category>?Categories?{?get;?set;?}
}

相比起Post模型,多了ContentHtmlCategories改成列表

Service

關鍵的渲染部分介紹完了,講一下一些次要的~

Service的作用是把Post模型轉換成ViewModel

那直接上代碼吧

public?PostViewModel?GetPostViewModel(Post?post)?{var?vm?=?new?PostViewModel?{Id?=?post.Id,Title?=?post.Title,Summary?=?post.Summary,Content?=?post.Content,ContentHtml?=?Markdig.Markdown.ToHtml(post.Content),Path?=?post.Path,CreationTime?=?post.CreationTime,LastUpdateTime?=?post.LastUpdateTime,Category?=?post.Category,Categories?=?new?List<Category>()};foreach?(var?itemId?in?post.Categories.Split(",").Select(int.Parse))?{var?item?=?_categoryRepo.Where(a?=>?a.Id?==?itemId).First();if?(item?!=?null)?vm.Categories.Add(item);}return?vm;
}

雖然不用后端渲染方案,不過我還是保留了Markdig的后端渲染。

View

PS:Controller部分被我略過了,實在是太簡單,沒必要貼代碼了

這個好像也沒啥好介紹的,那還是不貼完整代碼了,詳細代碼在這:https://github.com/Deali-Axy/StarBlog/blob/master/StarBlog.Web/Views/Blog/Post.cshtml

使用Bootstrap的Grid布局做左右兩欄,左欄顯示文章的TOC目錄,右欄顯示文章的主體內容。

頁面頂部要展示分類的層級關系,不同分類之間用“/”分隔,但第一個分類前面不要有斜杠(復雜的表述方式)

這個需求的實現代碼是這樣

<div>分類:@foreach?(var?category?in?Model.Categories)?{@if?(Model.Categories.IndexOf(category)?>?0)?{<span>?/?</span>}<a?asp-controller="Blog"?asp-action="List"asp-route-categoryId="@category.Id">@category.Name</a>}
</div>

效果大概這樣:

3751791407cda4708803334185cd7658.png
image

然后還要優化一下時間的顯示

@Model.LastUpdateTime.ToShortDateString()
@Model.LastUpdateTime.ToString("hh:mm")

完成之后的效果如下

實現效果

d3a7822c19a3aafc2ff25e2b1256c016.png
image

大概就是這樣,后續可能會再優化一下頁面。

搞定~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/287220.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/287220.shtml
英文地址,請注明出處:http://en.pswp.cn/news/287220.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

關 于 解 析 php 的 問 題

在搭建discuz論壇的時候出的問題&#xff0c;上次搭建用的是2.2版本&#xff0c;這次下了個2.4版的Apache發現有好多地方不一樣&#xff1b;比如在order deny allow 方面就變了Deny from all變成Require all deniedAllow from all變成Require all granted今天在配置完后開始在瀏…

【攝影測量原理】第三章:雙像立體測圖

本章主要內容: 第一節 人眼的立體視覺和立體觀測第二節 立體像對相對定向和核線幾何第三節 立體像對的前方交會第四節 單元模型的絕對定向第五節 雙像解析攝影測量 第一節 人眼的立體視覺和立體觀測 1.1 人眼的立體視覺 人用雙眼判斷景物可判斷其遠近,得到…

linux源碼編譯emqttd,emqtt編譯及簡單測試記錄

emqtt&#xff1a;在Erlang中實現的MQTT客戶端庫和命令行工具&#xff0c;支持MQTT v5.0 / 3.1.1 / 3.1。下載源碼編譯cd emqtt & make運行./rebar3 shell測試1、初始化{ok, ConnPid} emqtt:start_link([{clientid, "2020"},{keepalive, 0},{proto_ver, v5},{ho…

《看聊天記錄都學不會C語言?太菜了吧》(18)2分鐘搞結構體

若是大一學子或者是真心想學習剛入門的小伙伴可以私聊我&#xff0c;若你是真心學習可以送你書籍&#xff0c;指導你學習&#xff0c;給予你目標方向的學習路線&#xff0c;無套路&#xff0c;博客為證。 本系列文章將會以通俗易懂的對話方式進行教學&#xff0c;對話中將涵蓋…

【攝影測量原理】第四章:解析空中三角測量

第一節 概述第二節 航帶法解析空中三角測量第三節 獨立模型法解析空中三角測量第四節 光束法解析空中三角測量第五節 GPS輔助空中三角測量第六節 機載POS系統對地定位 第一節 概述 空中三角測量 是立體攝影測量中,根據少量的野外控制點,在室內進…

setInterval和setTimeout的使用區別

setTimeout和setInterval的使用 這兩個方法都可以用來實現在一個固定時間段之后去執行JavaScript。不過兩者各有各的應用場景。 方 法 實際上&#xff0c;setTimeout和setInterval的語法相同。它們都有兩個參數&#xff0c;一個是將要執行的代碼字符串&#xff0c;還有一個是以…

「System Design」設計一個短鏈接系統

短鏈接系統可以把比較長的 URL 網址轉換成簡短的網址字符串&#xff0c;短鏈接的優勢是方便傳播。適合在一些對字符串長度有要求的場景中使用&#xff0c;比如短信&#xff0c;微博等&#xff0c;比如https://www.cnblogs.com/myshowtime/p/16227260.html轉換成短鏈接為https:/…

Android之頁面有變化用onWindowFocusChanged來監聽權限是否開啟

1 問題 我們需要在Activity里面監聽網絡變化、熱點是否開啟和關閉、GPS服務是否開啟、位置權限是否開啟等一些列行為。 2 思路 方法一: 如果是需要啟動activity進行權限申請,我們可以用如下組合模式 var intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)startA…

iOS中 Animation 動畫大全 韓俊強的博客

每日更新關注:http://weibo.com/hanjunqiang 新浪微博&#xff01; iOS開發者交流QQ群&#xff1a; 4463102061.iOS中我們能看到的控件都是UIView的子類,比如UIButton UILabel UITextField UIImageView等等 2.UIView能夠在屏幕的顯示是因為在創建它的時候內部自動添加一個CALa…

IROS 2017上,這些廠商將會給我們展示什么樣的黑科技?

相比起大多數AI學術會議&#xff0c;機器人領域最具影響力的學術會議IROS要“好看”得多。在這個學術會議上不僅會有AI和機器人領域最新的研究成果的論文展示&#xff0c;更有不少來自于科研機構和機器人領域公司機器人&#xff0c;向我們展示著展示機器之美。 比如&#xff0c…

《看聊天記錄都學不會C#?太菜了吧》(3)變量:我大哥呢?$:小弟我罩著你!

本系列文章將會以通俗易懂的對話方式進行教學&#xff0c;對話中將涵蓋了新手在學習中的一般問題。此系列將會持續更新&#xff0c;包括別的語言以及實戰都將使用對話的方式進行教學&#xff0c;基礎編程語言教學適用于零基礎小白&#xff0c;之后實戰課程也將會逐步更新。 若…

linux block設備,Linux I/O Block--塊設備的表示

塊設備的分區信息由struct hd_struct結構描述&#xff0c;其中最重要的信息就是分區的起始扇區號和分區的大小。所有分區信息都一起保存在gendisk的part_tbl結構中&#xff0c;同時每個分區的block_device也可以通過bd_part來查詢對應的分區信息。下圖描述了block_device,gendi…

【搶鮮版】ArcGIS 10.7手把手經典圖文安裝教程(附安裝包下載地址)

軟件更新真是個快,ArcGIS10.7已經亮相了!回頭想想,作者追隨ArcGIS已經有11個年頭了(從ArcGIS 9.2到ArcGIS10.7,每個版本都搶鮮使用,先睹為快),本文演示10.7完美安裝過程(附下載地址),親測可用! 目 錄 一、系統環境要求 二、軟件安裝過程 三、軟件下載地址 一、…

Android之解決ViewPager2+PhotoView滑動圖片花屏問題

1 問題 用ViewPager2和開源框架PhotoView(com.github.chrisbanes.photoview.PhotoView)組合實現滑動預覽圖片, 但是部分機型出現花屏效果 2 原因 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas…

請來圍觀:WPF開發的微信客戶端!!!

本文經原作者授權以原創方式二次分享&#xff0c;歡迎轉載、分享。原文作者&#xff1a;眾尋原文鏈接&#xff1a;https://www.cnblogs.com/ZXdeveloper/p/6058206.html公司的同事離職了&#xff0c;接下來的日子可能會忙碌&#xff0c;能完善DEMO的時間也會少了&#xff0c;因…

C#字符串、字節數組和內存流間的相互轉換 - IT浪潮之巔

定義string變量為str,內存流變量為ms,比特數組為bt 1.字符串>比特數組 (1)byte[] btSystem.Text.Encoding.Default.GetBytes("字符串");(2)byte[] btConvert.FromBase64String("字符串"); 補充&#xff1a; System.Text.Encoding.Unicode.GetBytes(str)…

ios-新浪微博-下拉刷新獲取最新的消息(解決消息重復的問題)(五)

2019獨角獸企業重金招聘Python工程師標準>>> 第一步 在上一篇博文的基礎上&#xff0c;利用新浪提供的since_id進行判斷&#xff0c;在刷新監聽的方法中&#xff0c;引入下面的代碼 結果如下圖 轉載于:https://my.oschina.net/iOSliuhui/blog/520495

sqlserver快速查找所有存儲過程中是否包含某字符

--將text替換成你要查找的內容 select name from sysobjects o, syscomments s where o.id s.id and text like %text% and o.xtype P --將text替換成你要查找的內容 SELECT ROUTINE_NAME, ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_DEFINITION LI…

《看聊天記錄都學不會Python到游戲實戰?太菜了吧》(7)我用函數寫了個特洛伊木馬

本系列文章將會以通俗易懂的對話方式進行教學&#xff0c;對話中將涵蓋了新手在學習中的一般問題。此系列將會持續更新&#xff0c;包括別的語言以及實戰都將使用對話的方式進行教學&#xff0c;基礎編程語言教學適用于零基礎小白&#xff0c;之后實戰課程也將會逐步更新。 若…

【經典回放】多種語言系列數據結構算法:隊列(C版)

一、隊列ADT以及C語言實現 1 隊列的原理以及ADT分析 隊列是說:把一些數據按先進先出來組織,如同日常生活中的排隊過程。 隊列最主要的操作是 <1> 數據加入隊列;<2> 從隊列中取出數據; 加入隊列只能加入到隊列尾巴上,而從隊列中取出數據、則只能是取出隊列…