6

我正在使用 Handlebars 和 Gulp 构建一个静态站点。这是我的文件夹结构:

app/
    content/
        intro.json
        header.json
        faq.json
        features.json
        footer.json
    templates/
        home.hbs
        partials/
            home-section.hbs
            header.hbs
            footer.hbs
    index.html
Gulpfile.js

home.hbs 的内容是这样的:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Test</title>
</head>
<body>
    {{> header}}
    {{> home-section}}
    {{> home-section}}
    {{> home-section}}
    {{> footer}}
</body>
</html>

我想将intro.json, faq.json, and传递features.json给每个home-section部分,以及header.jsontoheaderfooter.jsonto 页脚。

到目前为止,这是我在 Gulpfile 中的内容:

var gulp = require('gulp');
var handlebars = require('gulp-compile-handlebars');
var rename = require('gulp-rename');

gulp.task('html', function() {
  return gulp.src('./app/templates/*.hbs')
    .pipe(handlebars({}, {
            ignorePartials: true,
            batch: ['./app/templates/partials']
          }))
    .pipe(rename({
            extname: '.html'
          }))
    .pipe(gulp.dest('build'));
});

我一直无法弄清楚如何一次传递多个 JSON 文件,尤其是传递给home-sections. 提前致谢!

4

2 回答 2

4

第一个参数handlebars是您的全局上下文,可用于所有模板。您可以将单个 JSON 文件加载到上下文对象中,并将其用作第一个参数。

(肯定有更好的方法可以做到这一点,但是嘿,它又快又容易!)

var infoData = require('./app/content/info.json');
var faqData = require('./app/content/faq.json');
var featuresData = require('./app/content/features.json');

然后,您可以通过全局上下文将这些对象传递给您的车把函数

.pipe(handlebars({ info: infoData, faq: faqData, features: featuresData }))

一旦数据在您的上下文中,您可以像这样访问它:

{{> home-section content=info }}
{{> home-section content=faq }}
{{> home-section content=features }}

在您的home-section部分内部,您将拥有一个content对象,该对象将包含您传递给它的文件的数据。因此,如果您的info.json文件如下所示:

{ "header": "Info", "details": "This is some information" }

然后,您的home-content.hbs部分可以像这样访问数据:

<h2>{{ content.header }}</h2>
<p>{{ content.details }}</p>
于 2017-01-16T03:50:41.283 回答
3

不幸的是,gulp-compile-handlerbars函数只接受两个参数,第一个是传递给模板的所有数据。这意味着您必须一起加载所有 json 文件并将它们作为单个对象传递。

你可以用一个小助手来做到这一点,比如:

function requireJsons(fileNames) {
  return fileNames.reduce(function(jsons, fileName) {
    jsons[fileName] = require('app/content/' + fileNames[i] + '.json');
    return jsons;
  }, {});
}

您可以使用它为所有模板构建数据对象:

var data = requireJsons(['intro', 'header', 'faq', 'features', 'footer']);

gulp.task('html', function() {
  return gulp.src('./app/templates/*.hbs')
    .pipe(handlebars(data, {
      // ...

如果您总是需要从app/content目录加载所有 json 文件,您可以使用readdirSync获取所有 .json 文件名,然后将它们传递给requireJsons

var path = require('path');
var fileNames = fs.readdirSync('app/content')
  .filter(function(fileName) {
    return path.extname(fileName) === '.json';
  });
var data = requireJsons(fileNames);

当然,如果速度很重要,您可以将两者结合为一种方法,该方法可以一次性加载 json 并构建data对象。


另一种选择是可能单独编译每个模板并将适当的数据传递到每个编译中。像gulp-foreach这样的工具会很有帮助。

于 2017-01-16T04:29:16.333 回答