【问题标题】:How to combine JSON and Handlebars from partials into HTML with Gulp?如何使用 Gulp 将 JSON 和 Handlebars 从部分组合成 HTML?
【发布时间】:2017-01-16 03:04:32
【问题描述】:

我正在使用 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.jsonfaq.jsonfeatures.json 传递给每个home-section 部分,并将@​​987654327@ 传递给headerfooter.json 到页脚。

这是我目前在 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。提前致谢!

【问题讨论】:

    标签: json gulp handlebars.js gulp-compile-handlebars


    【解决方案1】:

    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>
    

    【讨论】:

    • “在您的home-section 中,您将拥有一个content 对象是什么意思?请给我看看这个的代码好吗?
    • @Ryan 当您渲染一个车把部分时,您传递给它的参数随后会根据您使用的参数的名称在部分模板中可用。因此,如果您使用{{&gt; home-section thing=info }} 插入您的部分,您的home-section 部分将可以访问包含info 内容的变量thing
    【解决方案2】:

    不幸的是,gulp-compile-handlerbars 函数只接受two arguments,第一个是传入模板的所有数据。这意味着您必须将所有 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-02-02
      • 2018-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-02
      • 1970-01-01
      • 1970-01-01
      • 2016-10-10
      相关资源
      最近更新 更多