1

上篇链接: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结合起来~不过我们将在下一章开始,对我们的系统进行一个推倒重来,重新规划的工程,敬请期待!


Nark
372 声望17 粉丝