Gulp task to merge JSON and Handlebars from partials into HTML

1.8k views Asked by At

I'm making a simple proof-of-concept website using JSON as a data source and Handlebars for a templating engine, with a view to 'merging' the two things into a static HTML file.

The website will be very modular, so each component will be built using a distinct Handlebars 'partial', which will each consume data from its own JSON file.

The development structure I have so far is like this:

src/
    models/
        header.json
        article.json
        footer.json

    partials/
        header.hbs
        article.hbs
        footer.hbs

    index.hbs

The contents of the index.hbs file is something like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Test App</title>
</head>
<body>
    {{> header}}
    {{> article}}
    {{> footer}}
</body>
</html>

The partials are very simple for now. e.g header.hbs contains:

<header>{{header}}</header>

I have the following gulp file gulpfile.js which goes part way to what I want to achieve:

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

gulp.task('default', function () {
    var templateData = {
        header: 'Welcome'
    },
    options = {
        batch : ['./src/partials']
    }

    return gulp.src('src/index.hbs')
        .pipe(handlebars(templateData, options))
        .pipe(rename('index.html'))
        .pipe(gulp.dest('dist'));
});

So far, it bundles in my partials together and outputs everything nicely, as HTML, in a file called dist/index.html.

The thing that's missing is the JSON data part. Currently the JSON data being consumed by the partials is defined in the gulp file (the variable templateData) but I want each partial to consume data from the src/models JSON files to provide clear separation. The name of the JSON file will be identical to the name of the .hbs partial it's consumed by.

I'm unclear how to go about this. The gulp-compile-handlebars documentation suggests that using gulp-data will support what I need, but I'm struggling to piece together anything from the gulp-data documentation that works for my specific use-case.

Could anyone please suggest how I could modify my gulp file to accomplish this?

Many thanks.

1

There are 1 answers

1
AudioBubble On

If I understand the question, you can use gulp-data to return an object from your models .json file and it will be added to your tempateData object.

Use gulp-data to pass a data object to the template based on the handlebars file being processed. If you pass in template data this will be extended with the object from gulp-data.

So this worked for me.

gulp.task('default', function () {
    var templateData = {
        header: 'Welcome'
    },
    options = {
        batch : ['./src/partials']
    }

    return gulp.src('src/index.hbs')
        .pipe(data(function(file) {
            return require('./src/models/test.json');
        }))
        .pipe(handlebars(templateData, options))
        .pipe(rename('index.html'))
        .pipe(gulp.dest('dist'));
});

And you can modify the path to your .json file to match the name of the src .hbs file.