基于.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.mzph.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;对话中将涵盖…

「System Design」设计一个短链接系统

短链接系统可以把比较长的 URL 网址转换成简短的网址字符串&#xff0c;短链接的优势是方便传播。适合在一些对字符串长度有要求的场景中使用&#xff0c;比如短信&#xff0c;微博等&#xff0c;比如https://www.cnblogs.com/myshowtime/p/16227260.html转换成短链接为https:/…

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…

请来围观:WPF开发的微信客户端!!!

本文经原作者授权以原创方式二次分享&#xff0c;欢迎转载、分享。原文作者&#xff1a;眾尋原文链接&#xff1a;https://www.cnblogs.com/ZXdeveloper/p/6058206.html公司的同事离职了&#xff0c;接下来的日子可能会忙碌&#xff0c;能完善DEMO的时间也会少了&#xff0c;因…

ios-新浪微博-下拉刷新获取最新的消息(解决消息重复的问题)(五)

2019独角兽企业重金招聘Python工程师标准>>> 第一步 在上一篇博文的基础上&#xff0c;利用新浪提供的since_id进行判断&#xff0c;在刷新监听的方法中&#xff0c;引入下面的代码 结果如下图 转载于:https://my.oschina.net/iOSliuhui/blog/520495

《看聊天记录都学不会Python到游戏实战?太菜了吧》(7)我用函数写了个特洛伊木马

本系列文章将会以通俗易懂的对话方式进行教学&#xff0c;对话中将涵盖了新手在学习中的一般问题。此系列将会持续更新&#xff0c;包括别的语言以及实战都将使用对话的方式进行教学&#xff0c;基础编程语言教学适用于零基础小白&#xff0c;之后实战课程也将会逐步更新。 若…

linux修改windows注册表,妙招:让修改的注册表立即生效的几种方法

建站学院(LieHuo.Net)Windows文档Windows操作系统是全球最广泛&#xff0c;使用者最多的软件&#xff0c;熟悉Windows软件成了电脑操作者必不可少的功课&#xff0c;注册表作为“Windows的神经系统”非常重要&#xff0c;相信很多朋友都非常熟悉注册&#xff0c;在开始&#xf…

Android之通过用户名和密码连接指定wifi热点(兼容Android9.0和Android10.0和addNetwork(wifiNewConfiguration)返回-1问题)

1 需求 通过用户名和密码连接指定wifi热点,网上的代码乱七八糟,没几个可以用,我这边整理了下,测试了华为Android9.0和小米Android9.0和10.0和OPPO Android9.0 都没问题,直接回调结果就行。 2 问题 在Android10.0手机上 mWifiManager.addNetwork(wifiNewConfiguration);…

WPF怎么做新手引导界面?

本文经原作者授权以原创方式二次分享&#xff0c;欢迎转载、分享。原文作者&#xff1a;眾尋原文链接&#xff1a;https://www.cnblogs.com/ZXdeveloper/p/8391864.html这两天不忙&#xff0c;所以&#xff0c;做了一个简易的新手引导小Demo。因为&#xff0c;不是项目上应用&a…

《看聊天记录都学不会C语言?太菜了吧》(19)巩固开始,数字1、2、3、4能够组成多少个 3 位数的不同的排列

若是大一学子或者是真心想学习刚入门的小伙伴可以私聊我&#xff0c;若你是真心学习可以送你书籍&#xff0c;指导你学习&#xff0c;给予你目标方向的学习路线&#xff0c;无套路&#xff0c;博客为证。 本系列文章将会以通俗易懂的对话方式进行教学&#xff0c;对话中将涵盖…

【经典回放】多种语言系列数据结构算法:串(C版)

我们这里说的串、就是标准的C语言的串,这点,和我们教材中另行定义的串并不一致。我们这里强调仅仅是按C语言的标准处理串,是因为你会按C语言的标准构造串、而不是按其它的模式定义的。在我们的教材上,串相当与一个: struct ElemType {char *str; }; 构造的顺序表、或者是…

可以只读的 ServiceCollection

可以只读的 ServiceCollectionIntro在 .NET 7 Preview 4 中&#xff0c;ServiceCollection 可以声明为只读了&#xff0c;这使得我们可以有效避免在构建了 ServiceProvider 之后再新增服务&#xff0c;导致服务注册失败。Sample在新的版本中&#xff0c;ServiceCollection 新增…

阿里云与中国联通首个公共云平台上线

11月8日&#xff0c;阿里云与中国联通关于公共云合作的首个项目&#xff1a;浙江联通“沃云Powered by Alibaba cloud” 平台&#xff08;cloud.10010zj.com.cn&#xff09;正式发布上线。该平台将以沃云品牌为客户提供“阿里云联通”服务&#xff0c;结合阿里云技术及浙江联通…

IBM X System ServerGuide 8.41 服务器 系统安装 引导盘

IBM X System ServerGuide 8.41 支持操作系统: 32位: Microsoft Windows 2003/2003 R2 (Enterprise, Standard, Web and DataCenter UV) Microsoft Small Business Server 2003/2003 R2 (Standard/Premium Edition) Microsoft Windows 2008 (Enterprise, Standard, Web and Dat…