Hugo-seth / blog

blog
https://hugo-seth.github.io/blog/
32 stars 1 forks source link

ejs 的 layout 实现方法 #6

Open Hugo-seth opened 7 years ago

Hugo-seth commented 7 years ago

ejs本身是不支持的layout的,三年前就有人提了PR实现了layout和block(详情请戳),但一直都没被合并,不懂是因为什么。

在进去本文的主要内容之前,先回顾一下ejs的项目文档提供了哪几种用法(项目链接):

可以说功能已经比较齐全了。但是既然有 include,为什么没有 extend 呢?相信用过 jade 的朋友一定会发出这样一句怒吼。这就是我今天要讲的内容。

用 express 的同学不必担心这个问题,因为有一个插件叫ejs-locals,用法写得非常清楚,看一遍基本都会了。

那我要是用的 koa 呢?大家肯定会说:mdzz,肯定有插件的,搜一下不就行了。是的,插件是有,我搜了好久终于找到一个叫 koa-ejs 的(也许是我的英语太水了)。但不要高兴的太早,因为我估计没多少人能一下就看懂它的 README,反正我是看不懂。不过经过我的脑补及实践后已经彻底掌握了它的套路。

var koa = require('koa');
var render = require('koa-ejs');
var path = require('path');

var app = koa();
render(app, {
  root: path.join(__dirname, '/app/views'),
  layout: 'layout', // default layout
  viewExt: 'ejs',
  cache: false,
  debug: true
})

app.use(function *() {
  yield this.render('pages/index', {
    title: 'Hugo Blog',
    param: '<h2>Hello world</h2>',
    star: 'Mayday'
  })
});

其他的没什么好说的,主要是 layout 属性是什么意思呢。

qq20161207-0

qq20161207-1

qq20161207-2

index 和 layout 文件和 render 的html如上图,includes/header 里就一句 <h1>hello world</h1>。相信大家已经知道 layout 属性是什么意思了,就是将模板文件 extend 到哪个layout(默认就是 root属性设置的文件夹下的 layout.ejs)。这里就会有一个问题了,我们肯定不可能所有的页面都套同一个 layout 吧,那我们怎么修改它呢?如下:

app.use(function *() {
  yield this.render('pages/index', {
    layout: 'detail-layout', // 换成detail-layout.ejs or layout: false 不嵌套
    title: 'Hugo Blog',
    param: '<h2>Hello world</h2>',
    star: 'Mayday'
  })
});

知道了这些,我们就可以愉快的用 ejs 了。