Reputation: 3428
I'm building a static site using Handlebars and Gulp. Here's my folder structure:
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
The content of home.hbs is this:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test</title>
</head>
<body>
{{> header}}
{{> home-section}}
{{> home-section}}
{{> home-section}}
{{> footer}}
</body>
</html>
I want to pass in intro.json
, faq.json
, and features.json
to each of the home-section
partials, and header.json
to header
and footer.json
to footer.
This is what I have in my Gulpfile so far:
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'));
});
I haven't been able to figure out how to pass more than one JSON file at a time, especially to the home-section
s. Thanks in advance!
Upvotes: 6
Views: 3408
Reputation: 35501
Unfortunately, gulp-compile-handlerbars
function only takes two arguments, the first one being all the data passed into your templates. This means you have to load up all your json files together and pass them as a single object.
You can do this with a small helper like:
function requireJsons(fileNames) {
return fileNames.reduce(function(jsons, fileName) {
jsons[fileName] = require('app/content/' + fileNames[i] + '.json');
return jsons;
}, {});
}
Which you can use to build the data object for all your templates:
var data = requireJsons(['intro', 'header', 'faq', 'features', 'footer']);
gulp.task('html', function() {
return gulp.src('./app/templates/*.hbs')
.pipe(handlebars(data, {
// ...
If you always need to load all the json files from app/content
directory, you can use readdirSync to obtain all .json file names and then pass them to requireJsons
:
var path = require('path');
var fileNames = fs.readdirSync('app/content')
.filter(function(fileName) {
return path.extname(fileName) === '.json';
});
var data = requireJsons(fileNames);
Of course, if speed is important, you could combine the two into one method that loads the jsons and builds the data
object in a single pass.
Another option is to possibly compile each template individually and pass appropriate data into each compilation. A tool like gulp-foreach would be helpful.
Upvotes: 3
Reputation: 1052
The first parameter to handlebars
is your global context, available to all your templates. You can load your individual JSON files into a context object, and use that as the first parameter.
(There's definitely better ways to do this, but hey, it's quick and easy!)
var infoData = require('./app/content/info.json');
var faqData = require('./app/content/faq.json');
var featuresData = require('./app/content/features.json');
You can then pass these objects through the global context to your handlebars function
.pipe(handlebars({ info: infoData, faq: faqData, features: featuresData }))
Once the data is inside your context, you can access it like this:
{{> home-section content=info }}
{{> home-section content=faq }}
{{> home-section content=features }}
Inside your home-section
partial, you'll have a content
object that will contain the data of the file you passed into it. So, if your info.json
file looked like this:
{ "header": "Info", "details": "This is some information" }
Your home-content.hbs
partial could then access the data like this:
<h2>{{ content.header }}</h2>
<p>{{ content.details }}</p>
Upvotes: 5