gulphandlebars.jsgulp-datagulp-compile-handlebars

Gulp task to merge JSON and Handlebars from partials into HTML


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.


Solution

  • Since @Dan didn't provide a posted answer, his tip worked for me like a charm:

    gulpfile.mjs

    import gulp from 'gulp';
    import rename from 'gulp-rename';
    import hb from 'gulp-hb';
    
    
    const paths = {
        html: {
            src: 'src/templates/*.hbs',
            dest: 'build/pages/'
        }
    };
    
    function processHtml() {
        return gulp.src(paths.html.src)
            .pipe(hb()
                .partials('src/templates/partials/*.hbs')
                .data('src/templates/data/*.json')
            )
            .pipe(rename({
                extname: '.html'
            }))
            .pipe(gulp.dest(paths.html.dest));
    }
    
    gulp.task('serve', gulp.series(
        gulp.parallel(
            processHtml
        )
    ));
    

    Inside your hbs file you can refer to data from json by noting {{ jsonFileName.data }}

    Thanks for your help @Dan