在 Pug 模板中使用变量

如何在 Pug 里,把变量注入父模板。

我厂使用 Pug 作为 HTML 的预编译工具,写久了发现回不去了……Pug 写起来很高效,看久了习惯了阅读效率也很高,读了读文档,发现还有很丰富的可编程特性。于是我决定抛弃 Handlebars,以后都用 Pug 写模板了。

这次我厂官网改版,我就用 Pug 替换了 Handlebars,于是 build 脚本一下少了几十行,非常爽。其实我早就想这样做,不过卡在一个点:使用变量。

在 Pug 里可以这样使用变量:

- var name = 'meathill'

h1 hello #{ name }

以上代码将输出 <h1>hello meathill</h1>。这种用法比较简单,不过在 extends模板的时候,把变量放到哪里就不知道了,官方文档也语焉不详,我反复试了很多次无果,最终还是靠搜索找到了答案,原来要这样:

// Layout.pug
html
  block vars
    p 注意,这个 block 是重点,它出现在前面,用来注入变量
  head
    title #{ title } | My site
  body
    block content

// page.pug
extends Layout

block vars
  - var title = 'A blog'
  
block content
  h1 Blog title
  p blog content

使用 Pug 和 Stylus 开发小程序的 watch 脚本

小程序开发有两点比较蛋痛:1. 每个页面必须有3个文件,wxml,js,wxss;2. 使用 wxml 替代 html,使用 wxss 替代 css,使得默认的编译失效。这个脚本用来帮助我们使用 pug 和 stylus 进行开发。

首先,我试用了 Wepy,丑的一逼,遂放弃。

小程序开发有两点比较蛋痛:

  1. 每个页面必须有3个文件,wxml,js,wxss
  2. 使用 wxml 替代 html,使用 wxss 替代 css,使得默认的编译失效

Webpack 在这里不太适用,因为 1,我们并非要把所有代码打包到一起。WebStorm 的 File Watcher 也不适用,因为它输出的文件扩展名是固定的(跟 pug 和 stylus 源程序有关)。于是我经过摸索了,使用 gulp 脚本解决了这个问题,代码如下:

import gulp from 'gulp';
import pug from 'gulp-pug';
import rename from 'gulp-rename';

const pugFiles = 'pages/**/*.pug';

// 通用的 pug 处理,可以把 pug 转译并改名为 .wxml 文件
async function doPUG(path) {
  gulp.src(path)
    .pipe(pug())
    .pipe(rename({
      extname: '.wxml',
    }))
    .pipe(gulp.dest('./pages'));
}

// 将所有 pug 进行转译
gulp.task('pug', async () => {
  return doPUG(pugFiles);
});

// 侦听 .pug 文件的变化,并转译被修改的
gulp.task('watch', ['pug'], () => {
  gulp.watch(pugFiles, ({path}) => {
    doPUG(path);
  });
});

接下来,开发的时候,只要运行 gulp watch 即可。

用类似的方式,我们还能处理 stylus -> css,这里就不详述了,大家可以自己试一试。

完整的 gulpfile 在 GitHub 仓库里,请自行取用。