上篇链接:node.js + express4 写一个自己的博客网站[1]
- 0.前言
- 1.需求
- 2.技术选型
- 3.正文,动手
- 3.1 Hello, Express
- 3.2 Express 中的 Routing
- 3.3 认识一下 Middleware
- 3.4 引入markdown解析
- 3.5 模板引擎 Jade
3.4 引入markdown解析
在上一篇的末尾,我们已经可以给读者们提供所有文章的列表,并且在点击列表项后导航至对应文章的位置。只是在展现页面时我们简单的使用了
fs.readFile(filename, 'utf-8', function (err, data) {
if (err) res.send(err);
res.send(data);
});
这样的方式,直接将源文件的内容打印了出来。那么接下来的事情也不会很复杂,无非是将readFile()
后得到的字符串处理成html格式的内容即可。
关于markdown转换html的组件网上有不少现成的可用。经过了简单快速的试用后,我暂时敲定使用marked + pygmentize-bundled 的组合。码农么,自然优先关注代码着色高亮的功能。Pygmentize 在此间也算是鼎鼎大名了。
来看下简单的示例:
var marked = require('marked');
var pygmentize = require('pygmentize-bundled');
//设置pygmentize-bundled来做代码高亮转换
marked.setOptions({
highlight: function (code, lang, callback) {
pygmentize({ lang: lang, format: 'html' }, code, function (err, result) {
callback(err, result.toString());
});
}
});
//自定义方法,接收md文件内容,返回一个包含转换结果的回调函数
function markdown2html(data, callback) {
marked(data, function (err, content) {
return callback(err, content);
});
}
你问我为啥多此一举要在marked()方法外面再包装一层,因为我也不知道这玩意儿到底好不好用,以后万一发现有坑,多个中间层替换起来也方便。
好咧~那么组合一下~
fs.readFile(filename, 'utf-8', function (err, data) {
if (err) res.send(err);
markdown2html(data, function (err, content) {
if (err) res.send(err);
res.send(content);
});
});
打完收工,看看效果吧。
啥?你说还是难看?这…老子也只是个低端后台码农而已,css文件什么的自己去网上抄一份!
…
…
…
…
啥?抄回来了但是不会用?不知道往哪儿放?把css文件内容读取出来然后拼接到转换完成的html内容头上然后一股脑的res.send()
回去不就好了嘛!…
确实是有点麻烦的感觉…
那么是时候给我们的网站打扮打扮了!
3.5 模板引擎 Jade
所谓模板引擎,可以尝试这样简单的理解:首先回想一下C#中的String.Format()
,或是C语言中的printf()
,Python中的print()
等等类似的字符串格式化函数。我们提供一个模板参数,然后使用变量依照一定的规则填充模板,最终在运行时得到了格式化的字符串输出。依此继续,把我们的HTML页面想象成一个巨大的字符串,在其中的某些位置上使用变量填充替换,最终得到一个“动态”的页面:
<html>
<head></head>
<body>
<h1>{这里填写网页的标题}</h1>
<h2>{这里填写副标题}</h2>
<p>{这里是文章内容}</p>
<p>{这里是文章的创作日期与作者}</p>
</body>
</html>
这样一来,我们就可以在一定程度上将逻辑与页面分离,后台负责生成、处理与组织数据,前台则只关心数据如何被呈现。同时也避免了一大部分的手工重复劳动(想想看在这之前我们是如何生成页面的?在后台拼接半天的html再send出去,简直累的要死好吗)。上一节中提出的问题也在这里迎刃而解了:CSS这样的静态内容,直接写进模板就好,后端不再关心这些琐事了!
以此思路,我们进一步简化HTML中某些冗长的写法,再自创一些别出心裁的语法,然后再写个解释器翻译成HTML,比如
ul>li*(list.length)<-item.name in list
=>
<ul>
<li>list[0].name</li>
<li>list[1].name</li>
</ul>
额…随便开了一下脑洞…请勿当真…
总之,要像这样自己实现一个模板引擎也并非什么难事。
不过当然,要投入实际应用的模板引擎系统不但要考虑语法;效率也是非常重要的一部分,所以还是停止造轮子的企图,来看看express直接提供支持的模板引擎之一:Jade
…
…
…
看完了么?Jade的语法应该还算简单,这里不再浪费笔墨介绍了反正我后头也不打算用=.=。感兴趣的同学可以自己研究一下如何将Jade与Express结合起来~不过我们将在下一章开始,对我们的系统进行一个推倒重来,重新规划的工程,敬请期待!