5 years ago
Share this article Reddit Twitter Facebook Google+

如何用PHP Laravel设计一个简单的基于markdown的博客系统

最近我用PHP Laravel和Bootstrap 4重新搭建了我的个人网站。我需要一个简单的博客系统来写一些我的想法。经过考察一些已有的Laravel和PHP代码包,以及一些完整的博客系统,我决定从头写一个简单的博客系统。本文就写一些我搭建系统的思路和经验。

我的需求

为何从头创建

建立索引和元数据数据库

等等,不是需要完全基于文件的吗,怎么会有数据库?没错,博客内容本身是基于文件的,但出于性能考虑,博客相关的索引以及元数据要放在数据库中。数据库只是做为性能优化使用。数据库中的所有数据都是从博客文件解析出来的。也就是说,可以把数据库所有数据删除,然后从markdown文件恢复数据。这样数据库只是作为性能优化的手段,而不是博客系统的强依赖。这一点很重要,我们不仅在代码设计中要解耦,在系统设计中也要解耦。

数据库结构很简单,只有一个表保存诸如修改时间等信息的元数据,还有一个表保存tag信息。未来也许会增加别的表,但原则很简单,所有数据都是从博客文件中解析的。

数据库中的数据支持惰性创建,当打开一个博客页面时,系统发现数据库中没有相关会数据或者元数据过期时,会重新创建元数据。

当新增或者删除一篇文章时,需要重建索引来将变化反映到索引页面上。出于性能考虑博客引擎不会自动检测索引的变化。我用PHP写了一个工具来重建索引。这个工具是一个Laravel artisan命令,并重用了大部分博客系统代码。

由于数据库的数据除了惰性创建外几乎是只读的,我最早考虑用Sqlite。但是由于有其它模块需要用到数据库,最终还是选用了MySQL。

markdown到HTML的转换

市面上有不少够好的开源的markdown到HTML的转换库,我最终选用了Parsedown。不过我需要扩展它来给外部链接加上target="_blank"rel="nofollow"

解析markdown文件

博客重要的元数据,都是保存在markdown的一个特殊标记块里。在把markdown转换成HTML前,博客引擎解析并提取元数据块,并存到数据库里。元数据也许可以采用YAML之类的格式并用第三方库来解析,但我还是决定自己来解析简单的格式,因为这样花的时间比查找第三方库要快很多。

几条元数据的示例

update_time = 2019-01-20 15:19 GMT+08:00
title = 这是一个标题
summary = 这是一些概要
另外一行概要
tags = tag1, tag2

评论系统

先说说我对评论系统的要求

我在考察了一些基于PHP的文章评论系统以后,我曾打算自己从头写一个评论系统。我犹豫了好久,总感觉不值得再重新发明一个轮子,而且最重要的是,评论系统不是必须的。最后我决定使用第三方评论服务,比如HTML comment box (其实还有Disqus,不过我不是很喜欢)。幸运的是,在我使用第三方服务前,我发现了非常出色的代码库Commentics,它基本满足我的需求。

总结

这次从头写一个基于markdown的博客系统非常有意义。在花的时间不是很多的情况下,我有了一个完全满足我需求的博客系统,而且我还会慢慢增加新的功能。