Как объединить JSON и Handlebars из партиалов в HTML с Gulp?
Я строю статический сайт, используя 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
, а также features.json
каждому из home-section
частичные и header.json
в header
а также footer.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-section
s. Заранее спасибо!
2 ответа
Первый параметр для handlebars
это ваш глобальный контекст, доступный для всех ваших шаблонов. Вы можете загрузить свои отдельные файлы JSON в объект контекста и использовать его в качестве первого параметра.
(Определенно есть лучшие способы сделать это, но эй, это быстро и просто!)
var infoData = require('./app/content/info.json');
var faqData = require('./app/content/faq.json');
var featuresData = require('./app/content/features.json');
Затем вы можете передать эти объекты через глобальный контекст в вашу функцию handlebars
.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>
К несчастью, 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, {
// ...
Если вам всегда нужно загрузить все файлы json из app/content
каталог, вы можете использовать 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);
Конечно, если скорость важна, вы можете объединить два метода в один, который загружает jsons и создает data
объект в один проход.
Другой вариант - возможно скомпилировать каждый шаблон отдельно и передать соответствующие данные в каждую компиляцию. Такой инструмент, как gulp-foreach, будет полезен.